Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tentative definition of struct with incomplete type

Tags:

Consider the following as a C file:

static struct S a;

int main() {
  return (long)&a;
}

struct S {
  int b;
} s;

Based on my reading of the C11 spec, I believe this is undefined behavior. 6.9.2 states:

A declaration of an identifier for an object that has file scope without an initializer, and without a storage-class specifier or with the storage-class specifier static, constitutes a tentative definition.

and under a Semantics heading (not Constraints):

If the declaration of an identifier for an object is a tentative definition and has internal linkage, the declared type shall not be an incomplete type.

It seems that the declaration on the first line is a tentative definition, and that the object a has internal linkage, and yet struct S has incomplete type at the time of the declaration. So, I would expect this to violate the second quotation, thus resulting in undefined behavior.

However, GCC does not print any diagnostic when run with the --std=c11 -Wall -pedantic flags. Am I misunderstanding the standard, or does GCC not print a diagnostic for this type of undefined behavior?

like image 307
Shivam Sarodia Avatar asked Apr 16 '18 18:04

Shivam Sarodia


1 Answers

Yes this is undefined.

Undefined behavior is just what the term indicates, it is not defined by the standard. Any compiler may add its own definitions and thereby extend the standard, and is not obliged to diagnose any of them. In particular, gcc has some special ideas about tentative definitions. Code that uses these is not portable.

like image 192
Jens Gustedt Avatar answered Oct 13 '22 10:10

Jens Gustedt