vendredi 10 mars 2017

C++ - constructor call sequence different on GCC and clang

I have the following program:

#include <iostream>

#define PRINT_LOCATION()\
    do { std::cout << __PRETTY_FUNCTION__ << "\n"; } while (false)

struct foo
{
    int val;

    foo()
        : val(1)
    {
        PRINT_LOCATION();
    }

    foo(const foo& other)
        : val(other.val * 2)
    {
        PRINT_LOCATION();
    }

    foo(foo&& other)
        : val(other.val * 2)
    {
        PRINT_LOCATION();
    }
};

int main()
{
    foo f{foo{foo{foo{}}}};

    std::cout << "value = " << f.val << "\n";

    if (f.val == 1)
        throw f;
}

Compilation and execution:

[mkc /tmp]$ g++ -Wall -Wextra -pedantic -std=c++14 -O0 -o a.out main.cpp
[mkc /tmp]$ ./a.out 
foo::foo()
value = 1
foo::foo(foo&&)
terminate called after throwing an instance of 'foo'
Aborted (core dumped)
[mkc /tmp]$ clang++ -Wall -Wextra -pedantic -std=c++14 -O0 -o a.out main.cpp
[mkc /tmp]$ ./a.out 
foo::foo()
foo::foo(foo &&)
foo::foo(foo &&)
value = 4
[mkc /tmp]$

I know that the compiler is allowed to remove some constructor calls, but isn't it only allowed to do it when there are no side effects? It looks like Clang is correct here, is it a bug in GCC?

Aucun commentaire:

Enregistrer un commentaire