2015-06-16 11 views
6

Ermöglicht die C++ - Sprache den folgenden Code zum Drucken von z. 1 statt 16? Nach anderen Antworten würde ich ja raten, aber dieser Fall scheint speziell nicht abgedeckt worden zu sein.Kann Speicher für Referenzen innerhalb einer C++ - Klasse entfernt werden?

#include "iostream" 
#include "cstdlib" 
using namespace std; 

struct as_array { 
    double &a, &b; 

    as_array(double& A, double& B) 
     : a(A), b(B) {} 

    double& operator[](const int i) { 
     switch (i) { 
     case 0: 
      return this->a; 
      break; 
     case 1: 
      return this->b; 
      break; 
     default: 
      abort(); 
     } 
    } 
}; 

int main() { 
    cout << sizeof(as_array) << endl; 
} 
+0

* "aber dieser Fall scheint speziell nicht abgedeckt worden zu sein" * - Was genau ist in Ihrem Fall nicht abgedeckt? Nur dass die Referenzen Klassenmitglieder sind? –

+1

Fehle ich etwas? Da 'a' und' b' unabhängige Referenzen sind, wie würde der Compiler die Struktur implementieren, außer durch die Zuweisung von Platz für zwei Zeiger? –

+0

> was speziell an deinem Fall hast du keine Deckung? ja es war die Tatsache, dass die Referenzen Klassenmitglieder sind – user3493721

Antwort

5

Die Norm sagt unter [dcl.ref]:

Es wird nicht spezifiziert, ob ein Verweis erfordert Speicher

Auch ist es für den Compiler zu entscheiden, was die Größe eines Objekts ist, so dass Sie hier eine beliebige Zahl ungleich Null erhalten können.

Es gibt auch die als-ob-Regel (aka. Berechtigung zu optimieren). Daher wäre es legal, wenn der Compiler Speicher für diese Referenzen verwendet, wenn und nur wenn die Art der Verwendung der Referenzen dies erfordert.

Nachdem alles gesagt wurde; im Interesse eines stabilen ABI würde ich immer noch erwarten, dass ein Compiler diesen Referenzen Speicher zuordnet.

2

Die Art und Weise der Compiler Referenz Verhalten implementiert - einschließlich wo und wie sie gespeichert sind - nicht spezifiziert ist in dem C++ Standard. Folglich könnte ein Compiler "1 statt 16" drucken, während Sie fragen.

Getrennt, brauchen Sie nicht zu break nach return ing.

2

Ich glaube, dass

cout << sizeof(as_array) << endl; 

liefert immer den erforderlichen Speicher für zwei Zeiger auf der gegebenen Maschine zu verdoppeln, vielleicht mit Lücken erweitert Verpackungsvorschriften zu erfüllen. Optimieren bedeutet, die Größe des Speichers bestimmter Datenstrukturen zu reduzieren. Stattdessen kann der Compiler Ihren Code in einem realen Szenario komplett weg optimieren. Also, wenn Sie den Code haben:

double a=100; 
double b=200; 
as_array arr(&a, &b); 
std::cout << arr[0] << std::endl; 

bei der Optimierung der Speicher für die Struktur vollständig weg führen kann, weil der Compiler weiß, wie sich die Werte durch den Code behandelt werden. Aber der Ausdruck von sizeof (arr) gibt Ihnen immer noch die theoretische Größe der Struktur.

Wie auch immer: Wenn Sie bessere Ergebnisse erzielen wollen, sollten Sie besser Code schreiben! Machen Sie Methoden const, wenn sie const sind! Wenn Sie C++ 11 verwenden, verwenden Sie möglichst constexpr.

+1

Was führt Sie dazu, das zu glauben? – juanchopanza

+1

Die Definition der Struktur ist in einem ersten Schritt unabhängig von der Verwendung. Wenn Sie also den Compiler nach dieser theoretischen Größe fragen, was sollte in diesem Fall optimiert werden? Es gibt nichts, das ohne Kenntnis des Anwendungsfalls optimiert werden könnte. Ich bin kein Sprachanwalt, aber wie sollte die gegebene Größe optimiert werden, ohne etwas anderes zu wissen? – Klaus

Verwandte Themen