12

The following code prints out same address for both a and b using GCC (not tested with other compilers):

#include <stdio.h>

void show() {
    {
        static char a[0];
        printf("%p\n", a);
    }
    {
        static char b[0];
        printf("%p\n", b);
    }
}

int main() {
    show();
}

My question is does C standard allow multiple variables to have a same address or this is just an extension of GCC?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
so61pi
  • 780
  • 2
  • 7
  • 21

4 Answers4

21

The paragraph C11 6.7.6.2p1 says:

Constraints

  1. In addition to optional type qualifiers and the keyword static, the [ and ] may delimit an expression or *. If they delimit an expression (which specifies the size of an array), the expression shall have an integer type. If the expression is a constant expression, it shall have a value greater than zero.

As your program violates a shall (0 is not greater than zero), the program would have undefined behaviour, except that in this case it appears within the constraints section. As the section 4 Conformance says

4 Conformance

  1. In this International Standard, ''shall'' is to be interpreted as a requirement on an implementation or on a program; conversely, ''shall not'' is to be interpreted as a prohibition.

  2. If a ''shall'' or ''shall not'' requirement that appears outside of a constraint or runtime- constraint is violated, the behavior is undefined. Undefined behavior is otherwise indicated in this International Standard by the words ''undefined behavior'' or by the omission of any explicit definition of behavior. There is no difference in emphasis among these three; they all describe ''behavior that is undefined''.

Also, the 5.1.1.3p1 says:

  1. A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as undefined or implementation-defined. Diagnostic messages need not be produced in other circumstances. [9])

With footnote saying:

9) The intent is that an implementation should identify the nature of, and where possible localize, each violation. Of course, an implementation is free to produce any number of diagnostics as long as a valid program is still correctly translated. It may also successfully translate an invalid program.


Thus

  • C11 does not have arrays of size 0.

  • The presence of such arrays are a constraint violation

  • However, GCC allows zero-size arrays as an extension

  • A conforming C implementation must produce a diagnostics message upon such use.

  • That GCC compiles this one with default settings without outputting a diagnostics message even when -std=c11 is set makes gcc -std=c11 a non-conforming implementation.

  • The GCC documentation says that:

    [...] to obtain all the diagnostics required by the standard, you should also specify -pedantic (or -pedantic-errors if you want them to be errors rather than warnings).

  • Thus to use GCC to compile in such a manner that it conforms to say C11 standard, you must explicitly use at least gcc -std=c11 -pedantic; and then you will get:

    zerosizearray.c:5:21: warning: ISO C forbids zero-size array ‘a’ [-Wpedantic]
           static char a[0];
    
  • However, GCC will still compile your program, even if it is an incorrect program (unless you use -pedantic-errors); in such case naturally none of the requirements of the standard will apply.

Since the C standard does not really allow objects of size zero (if I read correctly, a struct definition must also have at least one member and so forth), and it is more of that that distinct objects must occupy distinct space in memory where the distinct addresses for objects come from; the standard doesn't specify anything about addresses of objects of size 0.

5

In Standard C, zero-size array is not allowed.

If you're compile it with -pedantic option using gcc. It will give warning, saying:

zero.c:3:6: warning: ISO C forbids zero-size array 'a' [->pedantic]

msc
  • 33,420
  • 29
  • 119
  • 214
3

As others have already said 0 length arrays are not allowed in standard C & GCC compiler allow it as an extension. I would like to add one more thing: behaviour of your program you posted in question is undefined. You must cast to void* when using %p format specifier because printf's %p format specifier expects an argument of type void*.

See this answer: printf and pointers

Community
  • 1
  • 1
Destructor
  • 14,123
  • 11
  • 61
  • 126
-2

that zero-length arrays is a gcc extension and is not supported by the standard library, the behavior depends on the implementation of gcc extension

you can see the GCC documents here

6.17 Arrays of Length Zero

a zero length array is known as flexible array

  • Flexible array members are written as contents[] without the 0.
  • Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero.
  • Flexible array members may only appear as the last member of a struct that is otherwise non-empty.
  • A structure containing a flexible array member, or a union containing such a structure (possibly recursively), may not be a member of a structure or an element of an array. (However, these uses are permitted by GCC as extensions.)
gatieme
  • 105
  • 9