2017-10-25 2 views
4

So etwas kam gerade in einer anderen Frage auf und weckte mein Interesse. Da Foo wird wie folgt erklärt:Aufrufen einer statischen Elementfunktion auf nicht vorhandenem Objekt

struct Foo 
{ 
    static void bar() {std::cout << "Bar!";} 
}; 

etwas zu tun, wie dies scheint ganz gut zu funktionieren:

std::vector<Foo> v; 
v[10].bar(); 

Allerdings ist diese Nutzung eigentlich legal? Was passiert, wenn bar() nicht als static deklariert wurde?

+0

Es ist legal. Wenn 'bar()' nicht statisch wäre, wäre es natürlich immer noch legal. –

+5

UB aufgrund des Zugriffs auf ein nicht vorhandenes Element von 'std :: vector'. –

+1

Der Aufruf der Funktion ist irrelevant, 'v [10]' ist UB bereits. –

Antwort

4

Nach [class.static]/1 (Hervorhebung von mir):

Ein statisches Element der Klasse X s bezeichnet werden kann, die qualifizierte-ID Ausdruck X :: s zu verwenden; Es ist nicht erforderlich, die Syntax des Klassenmitgliedszugriffs zu verwenden, um auf einen statischen Member zu verweisen. Ein statisches Member kann unter Verwendung der Zugriffssyntax für den Klassenmember auf verwiesen werden. In diesem Fall wird das Objekt Ausdruck ausgewertet.

v[10]Muss ausgewertet werden, bar statisch ist oder nicht, ist unerheblich. Der Vektor wird sicher außerhalb der Grenzen aufgerufen, also ist es definitiv undefiniertes Verhalten.

9

etwas zu tun, wie dies scheint ganz gut zu funktionieren:

Das bedeutet nicht, es ist OK.

Bitte http://c-faq.com/ansi/experiment.html lesen, die eine große Analogie von Roger Miller hat.

„Jemand sagte mir, dass im Basketball Sie nicht den Ball halten können und laufen bekam ich einen Basketball und versuchte es und es funktionierte gut "Er hat Basketball offensichtlich nicht verstanden."

Zugriff auf v[10] ist undefiniertes Verhalten. Es spielt keine Rolle, ob Sie eine Member-Funktion aufrufen, selbst der Zugriff auf v[10] ist nicht definiert. (Und wie im Kommentar erwähnt, wird der Objektausdruck auch beim Aufruf einer statischen Elementfunktion ausgewertet, was IMHO offensichtlich sein sollte, weil v[10] nicht in einem nicht bewerteten Kontext wie sizeof(v[10]) oder decltype(v[10]) verwendet wird).

Sie können nicht C++ Code mit der Ansicht schreiben "das scheint gut zu funktionieren" und davon ausgehen, dass das Programm korrekt ist.

+0

nette Analogie. Ich werde einen Basketball bekommen und es selbst ausprobieren;) – user463035818

+0

"Sie können nicht C++ Code mit der Ansicht schreiben" das scheint gut zu funktionieren "und davon auszugehen, dass das Programm korrekt ist." Fragt nicht "Ist das legal?" das genaue Gegenteil davon? Abgesehen davon ist die Frage natürlich rein hypothetisch, das Innenleben von Code wie diesem zu verstehen. Ich kann nicht verstehen, warum irgendjemand jemals so etwas tun möchte. – Knoep

+0

In Bezug auf Ihre Bearbeitung glaube ich nicht, dass es so offensichtlich ist.Man kann leicht in die Falle tappen, zu denken, dass, wenn ein Teil eines Ausdrucks nicht benötigt wird, er nicht ausgewertet wird (ich hatte diese Umwandlung mit einem C++ - Neuling selbst, über statische Mitglieder, btw). Also ich denke, es ist gut, dass der Standard es ausspricht. – StoryTeller

Verwandte Themen