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
Related
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 = { ... };
I am trying to return a string from a array with 4 hexadecimal values. I have a huge list of hex arrays and need to use it in multiple functions. That's why I want to create a function of comparing the hex arrays and return a string.
int comparehex(byte hex[]){
char * buffer = new char [16];
byte hex1[4] = {0x4C, 0x79, 0x52, 0xA8};
byte hex2[4] = {0xC5, 0x86, 0xA4, 0xB5};
for (byte i = 0; i <=3; i++){
if (hex1[i] != hex[i]){
break;
}
if (i == 3){
return "string";
}
}
return false;
}
The code that I wrote won't even compile:
main.cpp: In function ‘int comparehex()’:
main.cpp:46:14: error: invalid conversion from ‘const char*’ to ‘int’ [-fpermissive]
46 | return "string";
| ^~~~~~~~
| |
| const char*
How can I return a string?
Function Declaration general rule:
return_type function_name( parameter list );
in your case:
int comparehex(byte hex[])
return_type : int
function_name : comparehex.
parameters : byte array.
As per declaration, function is supposed to return int.
but as per your code
return "string"; // returns a STRING
}
}
return false; // return a boolean
To return a string output, declare the return_type as std::string as in.
to do that you need to include "string" library.
#include <string>
std::string comparehex(byte hex[])
Although the return of boolean is cast to int (implicit type conversion).it is not a good practice and is considered unsafe.
refer to Implicit type conversion in C for more details.
Here is an example of returning const char* with nullptr as a special type of "sentinel value" to mean "false":
There are a lot of potential things to address here, and we don't really understand your purpose of the function or use-case, but let me just address your immediate code and one viable solution.
There are many potential ways to handle this. Again, here is just one. But, I have to make some assumptions to even answer. Let's assume that:
Your function needs to return either a string literal OR false (or something equivalent to represent this).
This means you will NOT be generating a string at run-time inside the function. You will ONLY return a string literal (meaning: a compile-time-constant string with double quotes around it like this: "some string literal") which is set in your source code and fixed at compile-time. Otherwise, my example may not meet your needs, and would need some changes.
You will never need to return true. Rather, the existence of a string indicates true as well.
In this case:
// 1. Change this:
int comparehex(byte hex[])
// to this:
const char* comparehex(byte hex[])
// 2. change this:
return false;
// to this:
return nullptr;
// now this line is fine too:
return "string";
Now, the function returns either nullptr to indicate false, OR a string literal such as "string".
You'd simply check to see if "false" was intended by checking like this:
const char* str = comparehex(some_hex_array);
if (str == nullptr)
{
// `comparehex()` essentially returned `false`, so do what you need to do here
}
else
{
// str was set to some string, so use its value (ex: print it)
printf("%s\n", str);
}
Final notes:
Again, if you're generating a new string inside the function at run-time, rather than returning a string literal set at compile-time, the above 2 changes are not sufficient.
Also note that the above code is rather "C-like". It is perfectly valid C++, but only one of many ways to handle the above scenario.
And lastly, nullptr here can be considered a type of "sentinel value", which means simply that it is a special value of your return type (const char*) to indicate a special meaning: false in this case. And therefore, by extension, this sentinel value of nullptr also possesses the special meaning of whatever you intend "false" to mean.
Related
For another generic example of returning const char*, see my const char * reset_cause_get_name(reset_cause_t reset_cause) function in my answer in C here: STM32 how to get last reset status. I don't return NULL (the C analogue to C++'s nullptr) for cases where no match is found, but I could. (In my example I set it to "TBD" instead of NULL).
See also: What exactly is nullptr?
In your case, you could add another parameter for passing by reference:
int comparehex(byte hex[], std::string& result_string);
In your code, before returning, set the result_string parameter to the string you want to return.
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"
I have this block of code:
int myFunc( std::string &value )
{
char buffer[fileSize];
....
buffer[bytesRead] = NULL;
value = buffer;
return 0;
}
The line - buffer[bytes] = NULL is giving me a warning: converting to non-pointer type 'char' from NULL. How do I get rid of this warning?
Don't use NULL? It's generally reserved for pointers, and you don't have a pointer, only a simple char. Just use \0 (null-terminator) or a simple 0.
buffer[bytesRead] = 0; // NULL is meant for pointers
As a suggestion, if you want to avoid copying and all then, below can be considered.
int myFunc (std::string &value)
{
s.resize(fileSize);
char *buffer = const_cast<char*>(s.c_str());
//...
value[bytesRead] = 0;
return 0;
}
NULL ≠ NUL.
NULL is a constant representing a null pointer in C and C++.
NUL is the ASCII NUL character, which in C and C++ terminates strings and is represented as \0.
You can also use 0, which is exactly the same as \0, since in C character literals have int type. In C++, character constants are type char.
In C++, the following lines have me confused:
int temp = (int)(0×00);
int temp = (0×00int);
What is the difference between those 2 lines?
Both are invalid because you are using × instead of x:
test.cpp:6: error: stray '\215' in program
test.cpp:6: error: expected primary-expression before "int"
test.cpp:6: error: expected `)' before "int"
But even fixing that, the second still isn't valid C++ because you can't write 0x00int:
test.cpp:6:13: invalid suffix "int" on integer constant
The first is valid (after changing × to x) and assigns the value 0 to temp. The cast is unnecessary here though - you don't need a cast just because the constant is written in hexadecimal. You can just write:
int temp = 0x00;
Ways to cast:
int temp = (int)0x00; // Standard C-style cast
int temp = int(0x00); // Function-style cast
int temp = static_cast<int>(0x00); // C++ style cast, which is clearer and safer
int temp = reinterpret_cast<int>("Zero"); // Big-red-flag style unsafe cast
The fun thing about static_cast and reinterpret_cast is that a good compiler will warn you when you're using them wrong, at least in some scenarios.
Visual Studio 2005 for example will throw an error if you try to reinterpret_cast 0x00 to an int, because that conversion is available in a safe way. The actual message is: "Conversion is a valid standard conversion, which can be performed implicitly or by use of static_cast, C-style cast or function-style cast".
The first will assign 0 to temp
Second will result in compilation error.
When the scanner sees 0× it expects it to be followed with hexadecimal digit(s), but when it sees i which is not a valid hex digit it gives error.
The first one takes the hex value 0x00 as an int, and uses it to initialize the variable temp.
The second one is a compile error.
First line is a valid C++, which basically equate to
int temp = 0;
while the second one will fail to compile (as suggested by everyone here).