4

I'm learning C++ using the books listed here. In particular, I read about complete-class context and came to know that it includes function-body, default argument, noexcept-specifier etc. Now, to further clear my understanding of the topic, I wrote the following program where #1 and #2 works but #3 fails. I don't know why #3 fails because I read that all the three(function body, default argument and noexcept specifier) are included in the complete-class context.

struct A {
   constexpr static bool func() 
   { 
       return true; 
   }
   //--------------vvvvvv------->works as expected   #1
   void f(bool V1 = func())
   { 
      bool V2 = func(); //works as expected          #2
   }
   //-----------------vvvvvv---->DOESN'T WORK?       #3
   void g()  noexcept(func()) 
   {
      ;
   }

};

A complete-class context of a class is a

  • function body
  • default argument
  • noexcept specifier

As you can see the third point says "noexcept specifier" so i expected #3 to works as well but it doesn't.

So my question is why #3 doesn't work unlike #1 and #2? Demo

GCC gives the error with #3:

 error: 'static constexpr bool A::func()' called in a constant expression before its definition is complete
   20 |    void g()  noexcept(func())

Clang gives:

error: noexcept specifier argument is not a constant expression
   void g()  noexcept(func()) 
                      ^~~~~~
<source>:20:23: note: undefined function 'func' cannot be used in a constant expression
<source>:10:26: note: declared here
   constexpr static bool func() 

MSVC gives:

 error C2131: expression did not evaluate to a constant
<source>(20): note: failure was caused by call of undefined function or one not declared 'constexpr'
<source>(20): note: see usage of 'A::func'
Alex
  • 318
  • 1
  • 14
  • 3
    There's a lot of books on that list you are reading! From what particular book on that list did you read about *complete-class context*, and what was the page number? – Eljay Oct 08 '22 at 18:26

1 Answers1

3

The program is well-formed and all the three compilers are wrong in rejecting the code as noexcept-specifier is included in complete-class context as quoted in the question.

Here are the respective bug reports:

GCC rejects use of static constexpr member function in noexcept complete-class context

Clang rejects use of static constexpr member function in noexcept complete-class context

MSVC rejects use of static constexpr member function in noexcept complete-class context

Jason
  • 36,170
  • 5
  • 26
  • 60
  • Microsoft has decided it's not a bug: https://developercommunity.visualstudio.com/t/static-constexpr-method-is-not-constant-/10009811 – Spencer Oct 18 '22 at 15:06
  • @Spencer No, actually [they admitted that it is indeed a bug](https://developercommunity.visualstudio.com/t/MSVC-rejects-use-of-static-constexpr-mem/10166701#TPIN-N10167796-N10169206). First they were saying that it is not a bug but then I said that according to the current wording it is a bug to which they agree. See the complete [thread](https://developercommunity.visualstudio.com/t/MSVC-rejects-use-of-static-constexpr-mem/10166701#TPIN-N10167796-N10169206). – Jason Oct 18 '22 at 15:08
  • That's a **highly** qualified admission, followed by a long discussion about why the "bug" is unlikely to ever be addressed. More likely the Standard will change to follow [this defect report from 2013](https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1626) and remove the capability. – Spencer Oct 18 '22 at 15:28
  • @Spencer *"bug is unlikely to ever be addressed."* I'm not so sure about that because I came to know that the current wording(about including noexcept specifier in complete-class context) is completely intentional. This mean that just like in OP's example we're able to use `func()` as default argument at `#1` and also at initializer at `#2`, we should be able to use `func()` inside the noexcept-specifier as it is also a complete-class context. – Jason Oct 18 '22 at 15:33
  • The wording is from C++11, before `noexcept` affected a function's type. Per Jonathan Emmet @ Microsoft: _"given that no compiler I’ve tried has implemented this 10 year old feature I am unsure how much (if at all) the issue of complete-class-context noexcept-specifiers informed the design of these later features."_ – Spencer Oct 18 '22 at 15:39