Search code examples
c++ctypedefredefinition

Type redefinition of identical definition


If I wanted to use a type, let's say ulong (part of POSIX), but did not know whether it was defined already, is it guaranteed that redefinition with the same definition is benign? This works in GCC, but I am unsure if it is defined in the C Standard.

Example

#include <stdio.h>
#include <sys/types.h>  // POSIX

/* 'ulong' already defined as 'unsigned long' */

typedef unsigned long ulong; // (Benign?) redefinition

int main(void) {
    ulong n = 5;

    printf("Result: %ld\n", n);
    return 0;
}

Solution

  • Short Answer

    Yes, this is guaranteed by C11 and later, and C++98 and later.

    Long answer

    For C, Section 6.7.3 of the C11 Standard states:

    - a typedef name may be redefined to denote the same type as it currently does,provided that type is not a variably modified type;

    This means that a type may be redefined so long as each definition is identical. Section 6.7.5 goes even further to state that only the first of these definitions (or the only definition) will be used by the compiler.

    For C++, Section 7.1.3.3 of the C++98 Standard states:

    In a given scope1, a typedef specifier can be used to redefine the name of any type declared in that scope to refer to the type to which it already refers.

    This means that type redefinition is allowed in any non-class scope. Furthermore, in Section 7.1.3.6, it states:

    In a given scope, a typedef specifier shall not be used to redefine the name of any type declared in that scope to refer to a different type.

    This means that redefinition is disallowed when the definition (type, in the documentation) is changed. As a result, the only time when we are unable to redefine a type is when subsequent definitions differ from the first, or--as Section 7.1.3.8 states--if the type name describes any of the following:

    • an elaborated type specifier
    • a class definition
    • a constructor declaration, or
    • a destructor declaration

    source: https://port70.net/~nsz/c/

    1In C++03 and later, scope must be non-class