Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where in a declaration may a storage class specifier be placed?

Tags:

For example, let's consider the static storage class specifier. Here are a few examples of both valid and ill-formed uses of this storage class specifier:

static int a;        // valid int static b;        // valid  static int* c;       // valid int static* d;       // valid int* static e;       // ill-formed  static int const* f; // valid int static const* g; // valid int const static* h; // valid int const* static i; // ill-formed  typedef int* pointer; static pointer j;    // valid pointer static k;    // valid 

(The declarations marked "valid" were accepted by Visual C++ 2012, g++ 4.7.2, and Clang++ 3.1. The declarations marked "ill-formed" were rejected by all of those compilers.)

This seems odd because the storage class specifier applies to the declared variable. It is the declared variable that is static, not the type of the declared variable. Why are e and i ill-formed, but k is well-formed?

What are the rules that govern valid placement of storage class specifiers? While I've used static in this example, the question applies to all storage class specifiers. Preferably, a complete answer should cite relevant sections of the C++11 language standard and explain them.

like image 533
James McNellis Avatar asked Oct 25 '12 17:10

James McNellis


People also ask

What is declaration of storage class in C?

The four storage classes in C are declared in a block or program with the storage class specifiers, auto, register, extern, static. There is one more storage class specifier, 'typedef' used in the syntactic form, and does not reserve storage.

What is a storage class specifier?

A storage class specifier is used to refine the declaration of a variable, a function, and parameters. Storage classes determine whether: The object has internal, external, or no linkage. The object is to be stored in memory or in a register, if available.

Which of these are storage class specifiers?

The code below shows the declaration of storage class specifiers in C: The auto variable a is defined and printed in the main function. The register variable b is defined and printed in the test_func . The extern variable c is defined outside the functions and printed in the main function.


1 Answers

In summary, anywhere in the declaration specifier (See section 7.1 in the ISO/IEC 14882-2012), ie before the *. Qualifiers after the * are associated with the pointer declarator, not the type specifier, and static doesn't make sense within the context of a pointer declarator.

Consider the following cases: You can declare a normal int and a pointer to an int in the same declaration list, like this:

int a, *b; 

this is because the type specifier is int, then you have two declarations using that type specifier int, a, and a pointer declarator *a which declares a pointer to int. Now consider:

int a, static b;  // error int a, *static b; // error int a, static *b; // error 

which should look wrong (as they are), and the reason (as defined in sections 7.1 and 8.1) is because C and C++ require that your storage specifiers go with your type specifier, not in your declarator. So now it should be clear that that the following is also wrong, since the above three are also wrong:

int *static a; // error 

Your last example,

typedef int* pointer; static pointer j;    // valid pointer static k;    // valid 

are both valid and both equivalent because the pointer type is defined as a type specifier and you can put your type specifier and storage specifeir in any order. Note that they are both equivalent and would be equivalent to saying

static int *j; static int *k; 

or

int static *j; int static *k; 
like image 118
hexist Avatar answered Oct 14 '22 21:10

hexist