Search code examples
c++exceptionlanguage-lawyernoexceptexception-specification

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


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)?


Solution

  • 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.