Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is typedef a storage-class-specifier?

Tags:

c

typedef

I tried the following code

#include <stdio.h>

int main(void)
{
    typedef static int sint;
    sint i = 10;

    return 0;
}

and hit the following error:

error: multiple storage classes in declaration specifiers

When I referred the C99 specification, I came to know that typedef is a storage class.

6.7.1 Storage-class specifiers

Syntax

storage-class-specifier:
    typedef
    extern
    static
    auto
    register

Constraints: At most, one storage-class specifier may be 
             given in the declaration specifiers in a declaration

Semantics: The typedef specifier is called a ‘‘storage-class specifier’’ 
           for syntactic convenience only; 

The only explanation that I could find (based on some internet search and cross referring various sections in C99 specification) was syntactic convenience only to make the grammar simpler.

I'm looking for some justification/explanation on how can a type name have storage class specifier?

Doesn't it make sense to have a code like typedef static int sint;?

or Where am I going wrong?!

like image 472
Sangeeth Saravanaraj Avatar asked Dec 29 '11 22:12

Sangeeth Saravanaraj


People also ask

Is typedef a valid storage class in C?

In C, typedef is considered as a storage class like other storage classes (auto, register, static and extern), nevertheless the purpose of typedef is to assign alternative names to existing types.

What are the storage class specifiers?

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. The specifiers instruct the compiler on storing the variables.

Which is not a storage class specifier?

Which of the following is not a storage class specifier in C? Explanation: volatile is not a storage class specifier. volatile and const are type qualifiers.


2 Answers

Yes, typedef is a storage-class-specifier as you found in the standard. In part it's a grammatical convenience, but it is deliberate that you can either have typedef or one of the more "obvious" storage class specifiers.

A typedef declaration creates an alias for a type.

In a declaration static int x; the type of x is int. static has nothing to do with the type.

(Consider that if you take the address of x, &x has type int*. int *y = &x; would be legal as would static int *z = &x but this latter static affects the storage class of z and is independent of the storage class of x.)

If something like this were allowed the static would have no effect as no object is being declared. The type being aliased is just int.

typedef static int sint;
like image 56
CB Bailey Avatar answered Oct 12 '22 00:10

CB Bailey


Perhaps the standard should have called these things storage-class-or-typedef-specifier and said:

Constraints: At most, one storage-classor-typedef-specifier may be given in the declaration specifiers in a declaration

Then they wouldn't have had to added the note about the semantics.

The comment about the semantics is simply saying that typedef doesn't actually control anything about the storage used for the type (so it isn't semantically a 'storage specifier'), but that it is handled syntactically like the other storage-class-specifier, and therefore cannot be used with them.

So a typedef can't determine where a particular instance of type will be stored - that's determined by the actual declaration of the instance (either implicitly or explicitly).

Even if what you're looking for were permitted, it would be bad practice, I'm sure. Consider:

// in someheader.h
typedef static int sint;


// now in foo.c
#include "someheader.h"

int foo(void)
{
    sint i = 10;   // unless you're intimately knowledgeable about how 
                   //    `sint` is typedef'ed, this looks exactly like
                   //    an automatic


    // do some stuff that modifies `i`...

    return i;
}

sint bar(void)    // what does this mean?  is `bar()` static?
{
    return foo();
}

Note that is you use the preprocessor to get the 'static typedef' effect, that would make bar() a static function. Which might not be the effect you want. Maybe.

like image 29
Michael Burr Avatar answered Oct 12 '22 02:10

Michael Burr