Both GCC and Clang reject
extern "C" static void foo() {}
but accept
extern "C" {
static void foo() {}
}
Aren't these supposed to be equivalent?
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
}