What does it mean to declare a variable with a sto

2019-06-26 01:05发布

问题:

After reading through the ANSI C Yacc grammar specification I noticed the following are all valid:

register x;
auto y;
static z;
extern q;

This seems strange to me, as my understanding of type would suggest that none of these variables have a type. What do these mean? How are they type checked? How much memory is allocated?

回答1:

Before C99 if a type was not specified it defaulted to int this was supposed to be removed in C99 but many compilers support it even in C99 mode. For example in clang even using -std=c99 I only receive the following warnings as opposed to errors:

warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
  register x;
  ~~~~~~~~ ^
warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
  auto y;
  ~~~~ ^
warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
  static z;
  ~~~~~~ ^
warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
  extern q;
  ~~~~~~ ^

gcc also only provides a warning in this case, although using the -pedantic-errors flag will cause gcc to produce errors which is usually the case for extensions in gcc and usually for clang to but not in this case.

If we look at the draft C99 standard the Forward section says:

[...]Major changes from the previous edition include:

and includes the following bullet:

— remove implicit int

Update

From the Rationale for International Standard—Programming Languages—C section 6.7.2 Type specifiers:

new feature of C99: In C89, all type specifiers could be omitted from the declaration specifiers in a declaration. In such a case int was implied. The Committee decided that the inherent danger of this feature outweighed its convenience, and so it was removed. The effect is to guarantee the production of a diagnostic that will catch an additional category of programming errors. After issuing the diagnostic, an implementation may choose to assume an implicit int and continue to translate the program in order to support existing source code that exploits this feature.

The grammar you are using does predate C99 but as far as I can tell a newer version which is updated to reflect C11 does not differ much with respect to type specifiers in a declaration. So the grammar in this situation is not sufficient to enforce this constraint. You would have to goto the standard section 6.7.2 Type specifiers and see that it says:

At least one type specifier shall be given in the declaration specifiers in each declaration, and in the specifier-qualifier list in each struct declaration and type name.