Is “typedef” in between the type and the alias standard-conformant?

前端 未结 5 535
春和景丽
春和景丽 2021-02-06 20:59

I stumbled upon some code where the typedef keyword is in between the type and the alias name like in

int typedef INT;

It compiles

相关标签:
5条回答
  • 2021-02-06 21:34

    If you look at 7.1/1 you see this grammar for decl-specifier:, which shows that a type-specifier and the typedef keyword fall at the same point in the grammar, allowing you to interchange them as in the question (although as an aside never write code like this, it's not idiomatic at all).

    decl-specifier:

    storage-class-specifier
    
    type-specifier
    
    function-specifier
    
    friend
    
    typedef
    
    0 讨论(0)
  • 2021-02-06 21:45

    The typedef keyword is classified as a storage class specifier in C, though the standard explicitly remarks that that's for convenience in expressing the formal language syntax. It nevertheless follows that typedef can appear in exactly the same places that any other storage class specifier, such as extern or static, can appear. [C2011, 6.7.1/5]

    In fact, the syntax allows storage-class specifiers to be intermixed with type specifiers, type qualifiers, and other "declaration specifiers" in declarations. [C2011, 6.7/1, 6.7/6]

    Thus, yes, it is valid to put the typedef keyword after the type name, as in your example.

    0 讨论(0)
  • 2021-02-06 21:45

    I compile using:

    gcc -c -Wall -Wextra -pedantic -Wconversion -std=gnu99

    In the background, this means -Wold-style-declaration is set.

    Then the compiler outputs the following warning message:

    warning: 'typedef' is not a beginning of declaration [-Wold-style-declaration]
    

    without that parameter being set, the compiler handles the syntax with no problems

    So the posted syntax is within the standard, but can be confusing to the reader.

    0 讨论(0)
  • 2021-02-06 21:49

    TL/DR Version

    Yes, int typedef INT is conforming.

    James Michener Version

    C declaration syntax (C 2011 online draft):

    6.7 Declarations

    Syntax

    1    declaration:
            declaration-specifiers init-declarator-listopt ;
            static_assert-declaration

        declaration-specifiers:
            storage-class-specifier declaration-specifiersopt
            type-specifier declaration-specifiersopt
            type-qualifier declaration-specifiersopt
            function-specifier declaration-specifiersopt
            alignment-specifier declaration-specifiersopt
    ...

    What this says is that in a single declaration you can have a sequence of one or more declaration specifiers, where each declaration specifier can be a storage class specifier (auto, extern, static, typedef), a type specifier (int, float, char, etc.), a type qualifier (const, restrict, volatile, etc.), a function specifier (inline), or an alignment specifier.

    The order in which various specifiers appear doesn't matter; static const short int x; may be written as int static short const x, or int short const static x, etc. As a matter of practice, most people put the storage class specifier first, then any function or alignment specifiers (if necessary), then any type qualifiers, then type specifiers, so static const short int x is how most people would write that declaration.

    This syntax is what allows us to write types like long double or long long or unsigned long int, etc.

    Note that while the syntax allows arbitrary (and arbitrarily long) sequences of type specifiers, there's a semantic rule that only allows a relative few. You can't write short short short short x, for example, or long long long double y. Only the following sequences are allowed:

    Constraints

    2    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. Each list of type specifiers shall be one of the following multisets (delimited by commas, when there is more than one multiset per item); the type specifiers may occur in any order, possibly intermixed with the other declaration specifiers.
            — void
            — char
            — signed char
            — unsigned char
            — short, signed short, short int, or signed short int
            — unsigned short, or unsigned short int
            — int, signed, or signed int
            — unsigned, or unsigned int
            — long, signed long, long int, or signed long int
            — unsigned long, or unsigned long int
            — long long, signed long long, long long int, or
                signed long long int
            — unsigned long long, or unsigned long long int
            — float
            — double
            — long double
            — _Bool
            — float _Complex
            — double _Complex
            — long double _Complex
            — atomic type specifier
            — struct or union specifier
            — enum specifier
            — typedef name

    Addendum

    As Keith points out in the comment below, a future revision of the language may limit storage class specifiers to the beginning of the declaration, so int typedef INT may not be legal under a future compiler.

    0 讨论(0)
  • 2021-02-06 21:49
    typedef int INT
    

    RightWay to use typedef

    Wherever you use INT it will be replace by int datatype

    This main purpose is to only for long data string to simple value but in this case you can use normal int itself

    You can relay on just for test purpose use debugging you can understand very well

    0 讨论(0)
提交回复
热议问题