Difference between char and char[1]

Matthieu N. picture Matthieu N. · Nov 8, 2010 · Viewed 8.8k times · Source

In C++ what is the difference (if any) between using char and char[1].

examples:

struct SomeStruct
{
   char x;
   char y[1];
};

Do the same reasons follow for unsigned char?

Answer

Steve Jessop picture Steve Jessop · Nov 8, 2010

The main difference is just the syntax you use to access your one char.

By "access" I mean, act upon it using the various operators in the language, most or all of which do different things when applied to a char compared with a char array. This makes it sound as if x and y are almost entirely different. If fact they both "consist of" one char, but that char has been represented in a very different way.

The implementation could cause there to be other differences, for example it could align and pad the structure differently according to which one you use. But I doubt it will.

An example of the operator differences is that a char is assignable, and an array isn't:

SomeStruct a;
a.x = 'a';
a.y[0] = 'a';
SomeStruct b;
b.x = a.x; // OK
b.y = a.y; // not OK
b.y[0] = a.y[0]; // OK

But the fact that y isn't assignable doesn't stop SomeStruct being assignable:

b = a; // OK

All this is regardless of the type, char or not. An object of a type, and an array of that type with size 1, are pretty much the same in terms of what's in memory.

As an aside, there is a context in which it makes a big difference which you "use" out of char and char[1], and which sometimes helps confuse people into thinking that arrays are really pointers. Not your example, but as a function parameter:

void foo(char c);     // a function which takes a char as a parameter
void bar(char c[1]);  // a function which takes a char* as a parameter
void baz(char c[12]); // also a function which takes a char* as a parameter

The numbers provided in the declarations of bar and baz are completely ignored by the C++ language. Apparently someone at some point felt that it would be useful to programmers as a form of documentation, indicating that the function baz is expecting its pointer argument to point to the first element of an array of 12 char.

In bar and baz, c never has array type - it looks like an array type, but it isn't, it's just a fancy special-case syntax with the same meaning as char *c. Which is why I put the quotation marks on "use" - you aren't really using char[1] at all, it just looks like it.