2013-07-28 7 views
14

Wie ich weiß, compiletime C-like Strings werden im statischen Speicher als nur eine Instanz gehalten. Zum Beispiel habe ich beide true auf gcc 4.6 Beispiel unten ausgeführt. Aber ich frage mich, ob es immer wahr ist und tragbar sein kann. Verhalten auf C und C++ ist interessant.Strings in statischen Speicherinstanzen zählen

#include <iostream> 

bool amIportable(const char* value) { 
    const char* slocal = "Hello"; 
    return (slocal==value); 
} 

int main() { 
    const char* s = "Hello"; 
    std::cout << std::boolalpha 
      << amIportable(s) << '\n' 
      << amIportable("Hello") << '\n'; 
} 

Antwort

12

Nein, das ist nicht immer wahr, noch ist es tragbar.

Das Zusammenführen von identischen Zeichenfolgenliteralen ist eine Optimierung, die vom Compiler und dem Linker ausgeführt wird. Neuere Versionen von GCC und Microsoft Compiler unterstützen beide, aber nur wenn bestimmte Optimierungsschalter gesetzt sind.

Und es ist nicht nur ein "An" oder "Aus" -Funktion. Unterschiedliche Compiler und verschiedene Optimierungseinstellungen wirken sich auch darauf aus, wie aggressiv durchgeführt wird. Zum Beispiel werden Zeichenkettenliterale manchmal nur im Rahmen einer einzelnen Funktion gepoolt, zu anderen Zeiten geschieht dies auf der Ebene der Übersetzungseinheit und zu anderen Zeiten kann der Linker über mehrere Übersetzungseinheiten beteiligt sein.

Dies ist zulässig, da die C- und C++ - Standards dieses Verhalten als implementierungsabhängig belassen.

9

Nein, die Implementierung ist abhängig von C und C++.

C11 §6.4.5/7 Stringliterale

Es ist nicht spezifiziert, ob diese unterschiedlichen Anordnungen vorgesehen ihrer Elemente haben die entsprechenden Werte sind. Wenn das Programm versucht, ein solches Array zu ändern, ist das Verhalten nicht definiert.

11 C++ §2.14.5/12 Stringliterale

ob alle Stringliterale verschieden sind (das heißt, in nicht überlappenden Objekten gespeichert) ist die Implementierung definiert. Der Versuch, ein Zeichenfolgenliteral zu ändern, ist nicht definiert.

2

Aber ich frage mich ist es immer wahr

Nein, zumindest die C-Standard sagt so etwas wie „ob zwei identische Zeichenketten im selben Array gespeichert sind, ist die Implementierung definiert“.

2

Sie vergleichen zwei verschiedene Zeichenfolgenliterale, die mit denselben Wert haben. Nach dem C++ - Standard ist es Implementierung definiert, ob identische String-Literale den gleichen Speicher besetzen oder nicht (was bedeutet, dass die Implementierung dokumentieren muss, was es tut); nach dem C-Standard ist es nicht spezifiziert. (Ich nehme an, dass der C++ - Standard es der -Implementierung erlauben würde, etwas in der Art von "String Literalen mit identischem Inhalt zu dokumentieren, die sich dieselbe Instanz teilen, wenn sie sich in der gleichen Übersetzungseinheit befinden.

)

Wenn Ihr Ziel in der Lage ist, nur Zeiger zu vergleichen, ist die übliche Lösung ist eine Funktion (statisch zu verwenden, wenn es sich um ein Klassenmitglied) ist, die die Stringliteral zurückgibt:

char const* 
value() 
{ 
    return "Hello"; 
} 

bool 
isHello(char const* str) 
{ 
    return str == valule; 
} 

und Stellen Sie dann sicher, dass alle Instanzen der Zeichenfolge von abgerufen werden, value() aufrufen.