Home > other >  GCC compiles use of noexcept operator but clang and msvc rejects it
GCC compiles use of noexcept operator but clang and msvc rejects it

Time:10-22

While writing code involving noexcept I made a typo and was surprised to see that the program compiled in gcc but not in clang and msvc. Demo

struct C
{
    void func() noexcept
    {

    }
    void f() noexcept(noexcept(C::func)) //gcc compiles this but clang and msvc rejects this
    {
    }
};

So my question is which compiler is right here(if any)?

CodePudding user response:

The program is ill-formed and gcc is wrong in accepting the code because we cannot name a non-static member function in an unevaluated-context like decltype or sizeof or noexcept operator.

This can be seen from expr.prim.id:

An id-expression that denotes a non-static data member or `non-static member function of a class can only be used:

  • as part of a class member access in which the object expression refers to the member's class or a class derived from that class, or
  • to form a pointer to member ([expr.unary.op]), or
  • if that id-expression denotes a non-static data member and it appears in an unevaluated operand.

[ Example:

    struct S {
     int m;
   };
   int i = sizeof(S::m);           // OK
   int j = sizeof(S::m   42);      // OK

— end example ]

And since the id-expression C::func denotes the non-static member function but does not fall under any of the three listed categories, the program is ill-formed.

Here is the gcc bug:

GCC compiles invalid use of non static member function in noexcept operator


Note also that if C::func denoted a non-static data member(instead of member function) then the program would've been well-formed because of the third bullet in the above list. Demo

Similarly, if you were to write &C::func that would also have worked(well-formed) because of the 2nd bullet in the above quoted list.

  • Related