Vermeiden Sie eine unsachgemäße Std :: String -Initialisierung mit Null const char* mit g ++

StackOverflow https://stackoverflow.com/questions/2407711

  •  18-09-2019
  •  | 
  •  

Frage

A G ++ - Optionen, die eine unsachgemäße Initialisierung von STD :: String mit Null const char*erkennen können?

Ich war dabei, einige Int -Felder in std :: string zu verwandeln, dh:

struct Foo
{
   int id;
   Foo() : id(0) {} 
};

...wurde zu:

struct Foo
{
   std::string id;
   Foo() : id(0) {} //oooops!
};

Ich habe die schlechte 'ID' -Initialisierung mit 0 und G ++ völlig übersehen, und gaben mir überhaupt keine Warnungen. Dieser Fehler wurde in der Laufzeit festgestellt (STD :: String Constructor warf eine Ausnahme), aber ich würde wirklich gerne solche Dinge in der Kompilierungszeit erkennen. Gibt es irgendeinen Weg?

War es hilfreich?

Lösung

Ich denke, es ist tatsächlich ein undefiniertes Verhalten und nicht vom Compiler überprüft. Sie haben das Glück, dass diese Implementierung eine Ausnahme ausgelöst hat.

Sie können solche Probleme jedoch vermeiden, indem Sie angeben, dass Sie auf eine Standard- oder Nullinitialisierung auf Typ-Agnostische Weise möchten:

struct Foo
{
   X id;
   Foo() : id() {} //note empty parenthesis
};

Andere Tipps

Ich kann mir keine Möglichkeit vorstellen, dies zur Kompilierungszeit zu erkennen, also habe ich eine String Builder-Funktion geschrieben, die sich ordnungsgemäß mit Null-Zeigern befasst:

//  FUNCTION :      safe_string(char const* pszS)
//  PARAMATERS :    pszS        source string to build a string from (may be NULL or 0-length)
//  DESCRIPTION :   Safely builds a string object from a char*, even a NULL pointer
//  RETURNS :       string

template<class C>
inline basic_string<C> safe_string(const C* input)
{
    if( !input )
        return basic_string<C>();
    return basic_string<C>(input);
}

Ich benutze dies, wenn ich eine Zeichenfolge erstelle, und es besteht die Möglichkeit, dass die Eingabe null ist.

Es gibt Infrastruktur in GCC, um genau diese Art von Warnung zu produzieren:

void foo(const char* cstr) __attribute__((nonnull (1)));

void bar() {
    foo(0);
}

Wenn er zusammengestellt mit -Wnonnull (was impliziert durch -Wall) produziert:

warning: null argument where non-null required (argument 1)

Im Prinzip sollten Sie also in der Lage sein, den entsprechenden Systemheader zu ändern (oder besser zum Experimentieren, Ihre eigenen $ home/bits/basic_string.h kopieren und dann das System mit überschreiben können -isystem $HOME) Ähnlich:

basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())
    __attribute__((nonnull (1)));

Dies hilft jedoch nicht, weil (zumindest in 4.0.1) -Wnonnull wird in C ++ nicht unterstützt und das Attribut wird anscheinend ignoriert. Es ist nicht offensichtlich, warum das so ist; Vielleicht war es empfunden, dass es schlecht mit Überladung oder so interagierte.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top