6

I read a question on the difference between:

const char*

and

const char[]

where as for a while, I though arrays were just syntactic sugar for pointers. But something is bugging me, I have a pice of code similar to the following:

namespace SomeNamespace {
    const char* str = { 'b', 'l', 'a', 'h' };
}

I get, error: scaler object 'str' requires one element in initializer. So, I tried this:

namespace SomeNamespace {
    const char str[] = { 'b', 'l', 'a', 'h' };
}

It worked, at first I thought this may have to do with the fact that an extra operation is applied when it is a const char*, and GCC is never a fan of operations being performed outside a function (which is bad practice anyway), but the error does not seem to suggest so. However in:

void Func() {
    const char* str = { 'b', 'l', 'a', 'h' };
}

It compiles just fine as expected. Does anyone have any idea why this is so?

x86_64/i686-nacl-gcc 4(.1.4?) pepper 19 tool - chain (basically GCC).

1 Answers1

7

First off, it doesn't make a difference if you try to use compound initialization at namespace scope or in a function: neither should work! When you write

char const* str = ...;

you got a pointer to a sequence of chars which can, e.g., be initialized with a string literal. In any case, the chars are located somewhere else than the pointer. On the other hand, when you write

char const str[] = ...;

You define an array of chars. The size of the array is determined by the number of elements on the right side and, e.g., becomes 4 your example { 'b', 'l', 'a', 'h' }. If you used, e.g., "blah" instead the size would, of course, be 5. The elements of the array are copied into the location where str is defined in this case.

Note that char const x[] can be equivalent to writing char const* x in some contexts: when you declare a function argument, char const x[] actually is the same as char const*.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • 1
    When you write *"is the same"* should you not rather say *"can be implicitly converted"*? – IInspectable Sep 05 '13 at 00:12
  • I did not know this had different behavior in different contexts, thank you for clearing that up! – The Floating Brain Sep 05 '13 at 00:15
  • @IInspectable In reference to typedefs, would that be on an instance by instance basis or upon declaration of the type? – The Floating Brain Sep 05 '13 at 00:17
  • 2
    @IInspectable: No. Function arguments declared as `char const x[]` and `char const* x` are identical. However, they actually _are_ different when used as `typdef`s but I haven't quite figured out how. Here is a test: `void f(char const x[], char const* y) { std::cout << std::is_same::value << '\n'; }`. – Dietmar Kühl Sep 05 '13 at 00:22
  • Thanks for the clarification, I misinterpreted `char const x[]` to mean *any explicitly sized array*. Without a size argument they are indeed identical when used as types in a function signature. – IInspectable Sep 05 '13 at 00:34
  • @IInspectable: Even if you mentioned a size in the brackets, the type would still be a `char const*`: that is, `void f(char const x[10])` is equivalent to `void f(char const* x)`! Instead of `10` you can use any other positive value! – Dietmar Kühl Sep 05 '13 at 00:38
  • 2
    @DietmarKühl [Modified example](http://ideone.com/iZ318W) to demonstrate what I *think* you were referring to concerning differences as typedefs (and strangely, the same). That's a real noodle-baker. I think I may have finally found my first SO question. Thank you. – WhozCraig Sep 05 '13 at 00:44
  • @WhozCraig: That is, indeed, an interesting example! I haven't got to the bottom of that one, yet. – Dietmar Kühl Sep 05 '13 at 00:52
  • @DietmarKühl [Posted](http://stackoverflow.com/questions/18626126/why-are-char-and-char-as-typedefs-different-but-sometimes-not). I have a long drive, but will check in when I get home. Thanks for the brain food. – WhozCraig Sep 05 '13 at 00:56