c++language-lawyerlinkagestorage-class-specifierextern-c

What's the difference between `extern "C" /*...*/` and `extern "C" { /*...*/ }`


Both GCC and Clang reject

extern "C" static void foo() {}

but accept

extern "C" {
    static void foo() {}
}

Aren't these supposed to be equivalent?


Solution

  • No, they are not equivalent.

    Per [dcl.link]/8 the first form contains an implicit extern storage-class-specifier (not to be confused with extern "C", which is a linkage-specification) which conflicts with static. Whereas the second form does not impose any implicit storage-class-specifiers on the enclosed declarations, and is thus legal. In fact, [dcl.link]/5 gives an example for exactly this case:

    extern "C" {
        static void f4();  // the name of the function f4 has internal linkage,
                           // so f4 has no language linkage; its type has C language linkage
    }