0
unsigned char blind[32] = "and my kingdom too for a blinder";

This gives the error:

a value of type "const char [33]" cannot be used to initialize an entity of type "unsigned char [32]"C/C++(144)

I do not understand why this gives an error.

I'm trying to use a C library in a C++ project, and wanted to send the type the C library asked for.

Lundin
  • 195,001
  • 40
  • 254
  • 396
lukas
  • 3
  • 1
  • `"and my kingdom too for a blinder"` is shorthand for `{'a', 'n', 'd', '...', 'd', 'e', 'r', '\0'}`. – CompuChip May 17 '22 at 08:29
  • I think it might be easier to start with shorter strings: `sizeof("") == 1` (the only character is the hidden `'\0'`, `sizeof("a") == 2` (it is `'a'` followed by `'\0'`). – Krzysiek Karbowiak May 17 '22 at 08:47
  • Why was the C++ tag removed? The error message is C++ error, not a C error – Gerhardh May 17 '22 at 10:50

3 Answers3

1

C strings don't store their own length, so a 'null terminator' (the character \0) is used to mark the end of the string. This adds one extra byte to the string. Since you're initialising from a string literal, it's ignoring the [32] and using the length of your actual string, which includes the hidden terminator.

autumnalblake
  • 61
  • 1
  • 3
  • Thanks, when i changed to: ``` {'a','n','d',' ','m','y',' ','k','i','n','g','d','o','m',' ','t','o','o',' ','f','o','r',' ','a',' ','b','l','i','n','d','e','r'}, ``` it worked. – lukas May 17 '22 at 08:31
  • 1
    @lukas the null terminator is important. You have to keep it – Raildex May 17 '22 at 08:38
  • 2
    @lukas please note that with your solution you don't have a valid string anymore – Ingo Leonhardt May 17 '22 at 08:39
  • [32] is not ignored. – user253751 May 17 '22 at 08:41
  • Oh yeah, null terminator is kind of important. Thanks! – lukas May 17 '22 at 08:55
  • @Raildex Does the C char array not contain a \0? – lukas May 17 '22 at 08:56
  • @lukas `"and my kingdom too for a blinder"` is a string literal. It contains 32 "visible" character and an invisible null terminator - hence it is an array of 33 characters. What you need to do is change the number of characters of your variable: `unsigned char blind[33] = "and my kingdom too for a blinder";` – Raildex May 17 '22 at 09:01
  • @Raildex Yes I understand my issue now, thank you. But the line which thew and error in C++, compiled successfully in C. I guess C doesn't automatically add the NULL terminator? C and C++ handling string differently is the root cause? – lukas May 17 '22 at 11:52
1

The problem is that "and my kingdom too for a blinder" is a string literal of type const char[33] and not const char[32]. The last character is the null character '\0'. This means that the string literal "and my kingdom too for a blinder" is equivalent to:

{'a', 'n', 'd', ' ', 'm', 'y', ' ', 'k','i','n','g','d','o','m',' ','t','o','o',' ','f','o', 'r', ' ', 'a', ' ', 'b', 'l', 'i', 'n', 'd', 'e', 'r', '\0'}

Note in the above const char equivalent array there are 33 characters including the null character '\0'.

To solve this just change the size of the destination array as shown below:

//---------vv------------------------------------------->changed to 33
char blind[33] = "and my kingdom too for a blinder";
Jason
  • 36,170
  • 5
  • 26
  • 60
-2

There is no need to use unsigned char [] if you will only work with characters, symbols and numbers since all of that data is in the range of a simple char (which is basically an 8 bit data type in 2's complement).

Second, if you want to initialize a char [] rapidly, you can use the library string.h which is a standard and really useful library, just include it. Then just copy your string into the variable, considering that you must leave space for the end character '\0' which is implicitly placed in strings (char []) so the library string.h can detect the end of a string (char[]).

char blind[33];
strcpy(blind,"and my kingdom too for a blinder");
printf("%s", blind);

output: and my kingdom too for a blinder

LexFerrinson
  • 163
  • 7
  • 1
    Using `strcpy` this way means that if you get the length wrong, instead of a compiler error, you get a buffer overflow. Bad idea. – user2357112 May 17 '22 at 08:40
  • @user2357112 then check the lenght before using it, but assigning a string in the declaration is not generalist. If you want to declare a constant string for instance an error message then a macro #define should be used, not a char [] it is wasted memory. – LexFerrinson May 17 '22 at 08:45
  • Also, using `strcpy` is run-time assignment, not initialization. It's always slower than initialization, so all you achieved with this is _slower_ code. – Lundin May 17 '22 at 08:59
  • And if you are concerned about wasting memory then declare the array as `const char[]` in case it shouldn't be modified. – Lundin May 17 '22 at 09:00
  • const char[] keeps using the same memory as a char[], it is just not mutable – LexFerrinson May 17 '22 at 09:11
  • @LexFerrinson That depends on the system. On embedded systems you'll typically notice a significant difference as the read-only variable is moved from RAM to flash. – Lundin May 17 '22 at 10:57