9

gcc and msvc failed to compile this piece of code, with error msg namespace-scope anonymous aggregates must be static. But clang has no problem compiling this. https://godbolt.org/z/WecT6vP91

namespace {
    union {
        int a;
        long b;
    };
}

https://en.cppreference.com/w/cpp/language/union says

Namespace-scope anonymous unions must be declared static unless they appear in an unnamed namespace.

That seems a bug of gcc and msvc?


Edited:

However, Clang rejects to compile non-static anonymous union in named namespace nested in an unnamed one. Can the rule be changed to "... unless they appear in a direct or indirect unnamed namespace"(this seems have another problem, see below) or "... unless they have internal linkage"? Or why can not?

namespace {
  namespace ns {
    union {
      int a;
      long b;
    };
  }
}

According to External linkage for name inside unnamed namespace, names in unnamed namespace can have C language linkage. Clang even accepts non-static anonymous union that has C language linkage, without actually generating linking symbols though, which doesn't seem to make sense. Is it allowed by the standard? If it's allowed, what's the effect of extern "C" inside direct or indirect umnamed namespace?

namespace {
  extern "C" union {
    int a;
    long b;
  };
}
VainMan
  • 2,025
  • 8
  • 23

1 Answers1

0

GCC and MSVC just haven’t finished implementing P1787R6 yet; previously, the rule actually said that static was required regardless and Cppreference was wrong(!).

Davis Herring
  • 36,443
  • 4
  • 48
  • 76
  • _previously, the rule actually said that `static` was required regardless_ Ehm… E.g. C++17 says «Anonymous unions declared in a named namespace or in the global namespace shall be declared `static`.» https://timsong-cpp.github.io/cppwp/n4659/class.union.anon#2 – Language Lawyer Nov 29 '21 at 17:03
  • @LanguageLawyer: I think you’re right that I oversimplified, but what about a named namespace inside an unnamed one? – Davis Herring Nov 29 '21 at 18:11
  • @DavisHerring I just tried. Even Clang reject to compile non-static anonymous unions in named namespace inside an unnamed one. It seems that Clang just conforms to the standard "literally"(?). Maybe the rule can be "... unless they appear in an direct or indirect unnamed namespace"(this seems have another problem, see edited question description) or "... unless they have internal linkage" ? – VainMan Nov 30 '21 at 02:32