Welches ist das richtige Verhalten für das folgende Programm?Unterschiedliches Compilerverhalten für Ausdruck: 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();
}
Als ich es in meinem Linux RHEL 6.6 Workstation zu kompilieren, erhalte ich folgende Ergebnisse:
$ g++ -v
gcc version 5.1.0 (GCC)
$ g++ example.cpp -std=c++14 -Wall -Wextra -pedantic
$ ./a.out
Foo::Bar()
aber
$ 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.
und
$ 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: Das macht keinen Sinn. Der springende Punkt eines Sprachstandards ist es, Programm-Semantik eindeutig zu definieren. –
@LightnessRacesinOrbit: Während ich zustimme, dass es hier nicht der Fall ist, gilt deine Aussage im Allgemeinen nicht: Zum einen hast du - vor allem in C und C++ - UB und IB, dann ist JEDES Verhalten korrekt (für IB es muss nur dokumentiert werden). Dann haben Sie optionales Verhalten (z. B. Kopie Elision) und schließlich kann sogar ein internationaler Standard Fehler enthalten, die zu mehrdeutigen Situationen führen können. – MikeMB
@MikeMB: Fühlen Sie sich frei, mir ein Beispiel zu zeigen, wenn IB zu Compiler-Fehler in einer Implementierung, aber nicht anderen führt. Und UB zählt per Definition nicht. –