Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to initialize an unsigned char array from a string literal?

Tags:

c++

c-strings

I have a struct with an unsigned char[16] field that I'd like to initialize to zeros. The following (strongly simplified) code compiles fine with clang (OS X):

struct GUID {
    unsigned char bytes[16];
    GUID() : bytes("\0\0\0\0""\0\0\0\0""\0\0\0\0""\0\0\0") {};
}

Note I use 15 \0s because the 16th is the zero terminator of the string literal, and clang complains if you initialize a string with too many bytes.

Now, when I try to compile with GCC 4.5.3 (cygwin), I get:

error: incompatible types in assignment of 'const char [16]' to 'unsigned char [16]'

Why doesn't it work, and how can I make it work? (I could obviously loop through the array in the constructor, but I'd like to use the initialization list if possible, and I'd like to understand why it works in one compiler, but not the other.)

like image 495
jdm Avatar asked May 05 '13 16:05

jdm


3 Answers

A simple bytes() should be sufficient in this case. You could also consider bytes { 0,0,0,0.... }.

Also, use std::array, not T[]. Only fools use T[] when they could use std::array.

like image 143
Puppy Avatar answered Nov 06 '22 07:11

Puppy


Since we're dealing with POD its sufficient to explicitly construct bytes, which will result in the corresponding memory being 'zeroed':

struct GUID 
{
    unsigned char bytes[16];
    GUID() : bytes(){}
};

It's probably worth noting that if you didn't explicitly construct bytes in the initialization list, it would be left uninitialized

struct GUID 
{
    unsigned char bytes[16];
    GUID(){};
};

If the member variable were not a POD but instead a member object then instead of being left uninitialized it would call its default constructor.

like image 2
ed- Avatar answered Nov 06 '22 07:11

ed-


In the GUID constructor you can use memset(bytes, 0, sizeof(bytes));

like image 1
nosleduc Avatar answered Nov 06 '22 07:11

nosleduc