15
votes

The following C program:

#include <stdio.h>

int main(void)
{
    printf("%u %u %u\n",sizeof "",sizeof(""+0),sizeof(char *));
    return 0;
}

outputs 1 4 4 when compiled with GCC on Linux, but outputs 1 1 4 when compiled with Microsoft Visual C++ on Windows. The GCC result is what I would expect. Do they differ because MSVC has a bug or because sizeof(""+0) is undefined? For both compilers the behaviour (i.e. whether the middle value printed is equal to the first value or the last value) is the same no matter what string literal or integer constant you use.

A relevant reference in the ANSI C Standard seems to be 6.2.2.1 - Lvalues and function designators:

Except when it is the operand of the sizeof operator ... an lvalue that has type 'array of type' is converted to an expression that has type 'pointer to type' that points to the initial element of the array object and is not an lvalue.

Here though the "Except" should not apply because in sizeof(""+0) the array/string literal is an operand of + not sizeof.

3
Perhaps MS is doing some sort of optimization, replacing "" with '\0'? What happens if you take sizeof(""+(long long)0) ?Lundin
Replacing "" with '\0' would violate the type system. More interestingly, what's sizeof(""+1)?Fred Foo
technically you got UB because sizeof is of type size_t which must be printed using %zuphuclv

3 Answers

7
votes

Because "fooabc" is of type char[7], sizeof("fooabc") yields the same as sizeof(char[7]). However, arrays can be implicitly converted - the part you quoted - to pointers (some people wrongly call this "decay"), and since this is necessary for the arithmetic (+) to work, ""+0 will have a type of char*. And a char pointer can have a different size than the array. In that regard, MSVC's behavior seems broken.

1
votes

I guess it's an error of MSVC.

""+0 takes the address of "" (which is decayed in type char*) and sums 0 to it. That expression type is char*.

Play a little with it: what's the value of ""+0? and of ""+1? and of sizeof(""+1)?

1
votes

Looks like a bug in MSVC. Apparently it's optimizer removes the +0 before doing a proper type analysis.