Why can't I execute sizeof against the static char [] of another class?

Why does the following code generate a compilation error?


Edit: My source code was not clear - I split the code into separate files ...


First.h

class First { public: static const char* TEST[]; public: First(); }; 

First.cpp

 const char* First::TEST[] = {"1234", "5678"}; First::First() { uint32_t len = sizeof(TEST); // fine } 

Sizing in the First class seems fine, however ...

Second.h

 class Second { public: Second(); }; 

Second.cpp

 #include "First.h" Second::Second() { uint32_t len = sizeof(First::TEST); // error uint32_t elements = (sizeof(First::TEST) / sizeof(First::TEST[0])); // error } 

I get the following error: 'const char *[]': illegal sizeof operand

+4
source share
4 answers

sizeof only works with full types. const char* TEST[] not a full type until it is defined in First.cpp.

 sizeof(char*[10]) == sizeof(char*) * 10 == 40 sizeof(short[10]) == sizeof(short) * 10 == 20 // a class Foo will be declared class Foo; sizeof(Foo) == //we don't know yet // an array bar will be defined. int bar[]; sizeof(bar) == sizeof(int) * ? == //we don't know yet. // actually define bar int bar[/*compiler please fill this in*/] = { 1, 2, 3 }; sizeof(bar) == sizeof(int) * 3 == 12 // note bar is exactly the right size // an array baz is defined. int baz[4]; sizeof(baz) == sizeof(int) * 4 == 16 // initialize baz int baz[4] = { 1, 2, 3 }; sizeof(bar) == sizeof(int) * 4 == 16 // note baz is still 4 big, the compiler doesn't control its size 

To make this work on your own, you can:

  • add the size of the First::TEST array to its declaration ( static const char* TEST[2]; )
  • add a new static method that returns sizeof First::TEST . The method cannot be built-in; it must be defined in First.cpp.
+7
source

First of all, because the compilation of First.cpp and Second.cpp is independent of each other.

sizeof () in the second case (usually) is allowed at compile time, when only the declaration of the array is known, and the space for static not allocated cannot be calculated. See http://en.wikipedia.org/wiki/Sizeof#sizeof_and_incomplete_types

+3
source

With the extension Second.cpp becomes clearer. This is all that compiles (1 compilation unit):

 class First { public: static const char* TEST[]; public: First(); }; class Second { public: Second(); Second::Second() { uint32_t len = sizeof(First::TEST); // error uint32_t elements = (sizeof(First::TEST) / sizeof(First::TEST[0])); // error } } 

If you look here, First :: TEST obviously has no size, and sizeof (FIRST :: TEST) makes no sense.

Why not just use a method that returns the length of the TEST?

+2
source

For me, even the first sizeof(TEST) cannot be compiled, since TEST was not declared with a size (which is only allowed during connection).

If I change TEST[] to, say, TEST[10] , then both cases will compile.

Both results are what I expect.

Which compiler are you using?

+1
source

All Articles