Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

`constexpr` code expected to compile in c++20 but it doesn't. Why?

Tags:

c++

c++20

From here : https://github.com/PacktPublishing/C-Plus-Plus-20-Mastery---Pure-and-Unfiltered/blob/main/CoreLanguage/constexprChanges/constexprChanges/main.cpp

I got the following code snippet (I only changed &a with &b within the invocation of Invoke):

struct A {
    virtual int Get()const {
        return 1 ;
    }
};
struct B : A {

    constexpr int Get() const override {
        return 2 ;
    }
};
struct C : B {

    int Get() const override {
        return 3 ;
    }
};

constexpr int Invoke(A *a) {
    return a->Get() ;
}
int main() {
    A a ;
    B b ;
    C c ;
    static_assert(Invoke(&b) == 2) ;
    
}

It is my understanding that this code should compile just fine in C++20 since all the expressions involved in the static assert are constexpr. However when trying to compile using gcc 13.3.0 I get the following error:

<source>: In function 'int main()':
<source>:34:34: error: non-constant condition for static assertion
   34 |         static_assert(Invoke(&b) == 2) ;
      |                       ~~~~~~~~~~~^~~~
<source>:34:22:   in 'constexpr' expansion of 'Invoke((& b.B::<anonymous>))'
<source>:34:34: error: the value of 'b' is not usable in a constant expression
<source>:32:11: note: 'b' was not declared 'constexpr'
   32 |         B b ;
      |           ^
Compiler returned: 1

Now I did notice however the code in the github repo is for MVSC (since I see Visual Studio solution).

Can someone explain to me what's going on?

(A bit more context : I am looking in depth into C++20 and I am trying more or less to understand which resources are reliable).

Update:

The code actually compiles on x64 msvc v19.40 VS17.10

like image 956
user8469759 Avatar asked Oct 25 '25 05:10

user8469759


2 Answers

You can't call Get on an A*, it needs to be const.

constexpr int Invoke(const A *a) {
    return a->Get() ;
}

b also needs to be constexpr.

int main() {
    A a ;
    constexpr B b ;
    C c ;
    static_assert(Invoke(&b) == 2) ;
    
}
like image 194
robthebloke Avatar answered Oct 27 '25 20:10

robthebloke


constexpr code expected to compile in c++20 but it doesn't. Why?

Because the code you're looking at has multiple errors:
PacktPublishing/C-Plus-Plus-20-Mastery---Pure-and-Unfiltered/issues/1

From the above bugreport:

  1. It uses a which is not constexpr in a context where it must be.
  2. This also means that Invoke must take a const A*.
  3. The static_assert(Invoke(&a) == 2) ; should use b instead of a since B::Get is the function returning 2.

Also note that the author has confirmed the errors:

An old version of the file was uploaded by mistake. The correct file has been sent to the publisher and I'm waiting for them to upload it.

like image 36
Ted Lyngmo Avatar answered Oct 27 '25 19:10

Ted Lyngmo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!