Qual è il comportamento corretto per il seguente programma?Comportamento del compilatore diverso per expression: auto p {make_pointer()};
// example.cpp
#include <iostream>
#include <memory>
struct Foo {
void Bar() const {
std::cout << "Foo::Bar()" << std::endl;
}
};
std::shared_ptr<Foo> MakeFoo() {
return std::make_shared<Foo>();
}
int main() {
auto p { MakeFoo() };
p->Bar();
}
Quando compilo nel mio Linux RHEL 6.6 workstation, io ottenere i seguenti risultati:
$ g++ -v
gcc version 5.1.0 (GCC)
$ g++ example.cpp -std=c++14 -Wall -Wextra -pedantic
$ ./a.out
Foo::Bar()
ma
$ clang++ -v
clang version 3.6.0 (trunk 217965)
$ clang++ example.cpp -std=c++14 -Wall -Wextra -pedantic
example.cpp:16:4: error: member reference type 'std::initializer_list<std::shared_ptr<Foo> >' is not a pointer; maybe you meant to use '.'?
p->Bar();
~^~
example.cpp:16:6: error: no member named 'Bar' in 'std::initializer_list<std::shared_ptr<Foo> >'
p->Bar();
~^
2 errors generated.
e
$ icpc -v
icpc version 15.0.3 (gcc version 5.1.0 compatibility)
$ icpc example.cpp -std=c++14 -Wall -Wextra -pedantic
example.cpp(16): error: expression must have pointer type
p->Bar();
^
compilation aborted for example.cpp (code 2)
@ 0x499602D2: Non ha senso. Lo scopo di uno standard linguistico è definire in modo univoco la semantica del programma. –
@LightnessRacesinOrbit: Mentre sono d'accordo, che non è il caso qui, la tua affermazione non è vera in generale: per uno, hai - specialmente in C e C++ - UB e IB, nel qual caso QUALSIASI comportamento è corretto (per IB deve solo essere documentato). Quindi hai un comportamento opzionale (ad esempio copia elision) e, infine, anche uno standard internazionale può contenere errori che potrebbero causare situazioni ambigue. – MikeMB
@MikeMB: Sentitevi liberi di mostrarmi un esempio di quando IB porta all'errore del compilatore in un'implementazione ma non in un'altra. E UB non conta, per definizione. –