How to cast between integer and character in Red/System? - casting

If I try writing this:
foo: "whatever"
bar: 0
if foo/1 <> as char! bar [
;-- stuff
]
Then I am told:
Compilation Error: invalid target type casting: char!
But if I omit the as char and write:
foo: "whatever"
bar: 0
if foo/1 <> as char! bar [
;-- stuff
]
Then it tells me:
Compilation Error: left and right argument must be of same type for: <>
How do I cast an INTEGER! to a CHAR! in Red/System?

Currently there is no CHAR! datatype in Red/System.
The BYTE! datatype maybe what you would like to use.
Documentation: Red/System Datatypes

Related

Error C2440 when compiling a library with meson

I have code C++ that I want to compile as a library using meson where I get 2 kinds of errors
error C2440: 'initializing': cannot convert from 'const wchar_t [19]'
to 'const PWCHAR'
-note: Conversion from string literal loses const qualifier (see /Zc:strictStrings)
error C2664: '... cannot convert argument 2 from 'const wchar_t [6]'
to 'PWSTR note: Conversion from string literal loses const qualifier (see /Zc:strictStrings)
winnt.h uses typedef for wchar_t:
typedef wchar_t WCHAR;
typedef WCHAR *PWCHAR;
If I do this in my code I get Error C2440:
const PWCHAR Tokens[] = { L"A", L"B", L"C", L"D" };
If I change my code that error disappears:
const wchar_t * Tokens[] = { L"A", L"B", L"C", L"D" };
I know in C, the type of a string literal is array of char, but in C++, it's array of const char which causes this error.
I also know it is possible to change Zc:strictStrings in VStudio. But since I compile my code with meson how would I get rid of that error using meson?
With the definition
const PWCHAR Tokens[] = { ... };
you declare that Tokens is an array of constant pointers. The data that those pointers are pointing to are not constant.
And as literal strings are constant you can't use them to initialize the array.
The working definition:
const wchar_t * Tokens[] = { ... };
Or the alternative
wchar_t const * Tokens[] = { ... };
Here you declare that Tokens is an array of (non-constant) pointers to constant wchar_t data. Which is correct for literal strings.
If you want to be portable and follow the C++ standard, using PWCHAR is simply not possible.
If you want the pointers themselves to be constant, you need to add another const qualifier for them:
wchar_t const * const Tokens[] = { ... };
// ^^^^^
// makes the pointers constant
// ^^^^^
// makes the data constant
Or as mentioned in a comment: Use std::wstring (and other standard C++ containers):
// Or std::array if the size if known and fixed at compile-time
std::vector<std::wstring> Tokens = { ... };

CustomStringConvertible in enum

I have following enum in a class.
enum Attributes: String, CustomStringConvertible {
case eventDate
case eventName
case eventType
case country
var description: String {
return self.rawValue
}
}
When I try have the following code, compiler complains with following error.
var attributesList: [String] {
return [
Attributes.eventDate, //<-- Compiler error on this row
Attributes.eventName,
Attributes.eventType,
Attributes.country]
}
Cannot convert value of the type 'Attributes' to expected element type 'String'
Shouldn't the "CustomStringConvertible" protocol return the "description"?
What is wrong in the above code?
TL;DR - It doesn't work because an array of Attributes cannot be assigned to an array of Strings, they are both mismatched types, and Swift does not do automatic conversion between types, and an explict conversion needs to be specified.
In Swift, when you initialise an array using an array literal, the following happens under the hood:
let words = ["hello", "world"]
The compiler recognises that an array literal is being assigned to a variable named words. Since we have not specified the type of the words, implicitly an array is assumed. The type of the elements underlying the array is determined based on the contents of the array literal.
In this case, the array literal is a collection of String types; this is easily understood by the compiler
Since the LHS type is an array, the RHS structure is an array literal, and since the LHS type (Array) conforms to a pre-defined protocol called ExpressibleByArrayLiteral which has an associated type constraint to match Element, the compiler will actually be converting our line to the following
Example:
let words = [String].init(arrayLiteral: ["hello", "world"]) // we do not call this init directly
This is how initialising with array literals work. In the above example, since we did not specify the type of array, the implicit type setting will work. If we specified a mismatched type, the assignment will fail, since ExpressibleByArrayLiteral requires the associated Element type of the array literal and the actual array you are assigning to to match.
So the following fails:
let words:[String] = [1, 2] // array literal has Element=Int, array has Element=String
This also shows that there is no implicit type conversion between Int and String, even though Int conform to CustomStringConvertible.
In your case, you are trying to assign an array literal consisting of Attributes to an array of String. This is a type mismatch. This is the reason it fails.
If you state protocol conformance, the following line will work:
var attributesList: [CustomStringConvertible] {
return [
Attributes.eventDate,
Attributes.eventName,
Attributes.eventType,
Attributes.country
]
}
// note that we have an array of CustomStringConvertible protocol,
// each element here is still of Attributes type
// a type conforming to a protocol can be cast to an instance
// of that protocol automatically
// The above initialisation works simply because the following
// also works without any further action required
// let a:CustomStringConvertible = Attributes.country
If you really want a list of string values, you need to map this to a string explicitly:
var attributesList1: [String] {
return [
Attributes.eventDate,
Attributes.eventName,
Attributes.eventType,
Attributes.country
].map { $0.description }
}
var attributesList2: [String] {
return [
Attributes.eventDate.description,
Attributes.eventName.description,
Attributes.eventType.description,
Attributes.country.description
]
}

Setting CHAR16* to a #define string?

I'm a little confused on the proper way to do this. I have a #DEFINE that contains a string, and I have a CHAR16* that I want to set to that string. How would I properly do this? I've tried:
#DEFINE MYSTRING "HELLO"
CHAR16* THISONE;
THISONE = MYSTRING;
Why won't this work? I want to be able to print out the string in THISONE. I get a compiler warning regarding incompatible types. I'm sure I'm missing something small?
You're defining a narrow string literal "HELLO", but trying to use a CHAR16 pointer to point to it. That's not a compatible assignment. As clang says:
example.cpp:9:13: error: assigning to 'wchar_t *' from incompatible type
'const char [6]'
THISONE = MYSTRING;
^ ~~~~~~~~
1 error generated.
(I changed the type from CHAR16 * to wchar_t * since I'm not on windows - the semantics are the same).
To fix it, you need to add an L in front of the string constant:
#define MYSTRING L"HELLO"
And then it will compile. In C, you're done. In C++, however, you will probably still get a warning:
example.cpp:9:15: warning: conversion from string literal to 'wchar_t *' is
deprecated [-Wdeprecated-writable-strings]
THISONE = MYSTRING;
^
example.cpp:3:18: note: expanded from macro 'MYSTRING'
#define MYSTRING L"HELLO"
^
1 warning generated.
Change the definition to:
const wchar_t *THISONE;
To fix that warning. I guess in your case that would be:
const CHAR16 *THISONE;
Editorial note - in the future, please show your real code. #DEFINE (with the capital letters) isn't valid C or C++.
You probably want something like:
// Update: As carl points out, there is more to this for wide chars
const CHAR16* THISONE = MYSTRING;
You can explore more about c-strings here and also from within this very site.
You probably want to assign it as a global variable. In this case you need:
#define MYSTRING "HELLO"
CHAR* THISONE = MYSTRING;
or
#define MYSTRING L"HELLO"
CHAR16* THISONE = MYSTRING;
If assignment is in function (main() or other) you can make assignment not at the same place as variable creation.
Actually, I'm not sure if there is such a type "CHAR16"

C++ create empty byte

I was wondering if you could help me with a small problem I have:
I am currently devloping in C++/Qt and got the following error message:
P:\Produkt\Savor_V100\webapi.cpp:84: error: C2664: 'CryptoPP::PasswordBasedKeyDerivationFunction::DeriveKey' : cannot convert parameter 1 from 'const char *' to 'byte *'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
The parameter in the function is not used, therefore I would like to pass an empty byte in there. After a bit of research I found out that a byte is just a simple unsigned char?
My code looks like this:
byte* unused;
qDebug() << CryptoPP::PasswordBasedKeyDerivationFunction::DeriveKey(CryptoPP::SHA1::StaticAlgorithmName(), CryptoPP::SHA1::BLOCKSIZE, unused, user->getPassword(), sizeof(user->getPassword()), user->getSerial(), sizeof(user->getSerial()), 0 );
As said in the comment, the issue here is with the first argument of the function, not with the third where you used unused. Since I guess you do need this parameter, you should try as suggested:
qDebug() << CryptoPP::PasswordBasedKeyDerivationFunction::DeriveKey(
reinterpret_cast<byte*>(CryptoPP::SHA1::StaticAlgorithmName()),
CryptoPP::SHA1::BLOCKSIZE,
0,
user->getPassword(),
sizeof(user->getPassword()),
user->getSerial(),
sizeof(user->getSerial()),
0 );

expected unqualified id before '\0'

I tried following things but I am getting the error
typedef '\0' DEFAULT_VALUE;
Error: expected unqalified id before '\0'`
typedef NULL DEFAULT_VALUE;
Error: expected unqalified id before __null
what I am doing wrong here?
The general syntax of a typedef is:
typedef existing_type new_type_name ;
Since '\0' and NULL are not existing types you get the error.
Since you want define constants you can use the const as:
const int DEFAULT_VALUE = '\0';
The keyword typedef defines synonym for existing type. Neither \0 nor NULL are type. May be you want something as follows:
#define DEFAULT_VALUE NULL