2016-07-28 20 views
5

Ich bin es gewohnt, __attribute__((nonnull)) zu verwenden, wenn ich Zeiger ausspreche, die nicht null sein sollten.Wann verwende ich "__attribute __ ((nichtnull))" vs "not_null <T*>"?

void f(int* ptr __attribute__((nonnull))); 

int main(){ 
    int* ptr = new int(1); 
    f(ptr); 
} 
void f(int* ptr){/*impl*/} 

Doch mit der GSL, gibt es auch den not_null<T*> Wrapper-Typ.
void function1 (gsl :: not_null n);

void f(gsl::not_null<int*> n); 

int main(){ 
    int* ptr = new int(1); 
    f(ptr); 
} 
void f(gsl::not_null<int*> n){/*impl*/} 

Unter der Annahme, die Sprache Einrichtungen sind dort die GSL-Version zu unterstützen, sollte ich immer jetzt not_null<T*> anstelle von __attribute__((nonnull)) verwenden?

Ich hatte den Eindruck, dass das Compiler-Attribut Optimierungen unterstützen kann, aber die Wrapper-Version wird in einen nicht zugeordneten Zeiger aufgelöst.

+2

Eine Frage, Is '__attribute __ ((nonnull)) 'portabel über große Compiler? – WhiZTiM

+0

Warum nicht Referenz oder 'span' verwenden? – Jarod42

Antwort

2

„sollte ich immer not_null anstelle von Attribut verwenden ((ungleich NULL)) jetzt

not_null scheint die bessere Lösung, und hier ist warum:

__attribute__((nonnull)) zu sein scheint gcc spezifisch, das bedeutet, dass nur gcc dieses Attribut für Optimierungen, Sicherheit, Sicherheit, statische Codeanalysatoren (etc, nennen Sie es) verwenden kann.Dies macht es nicht eine sehr gute Wahl, wenn Sie mehrere Compiler verwenden möchten.Microsoft hat zum Beispiel __assume, die verwendet werden können, um ähnliche Ergebnisse zu erzielen.

gsl::not_null ist nicht Teil der Standardvorlagenbibliothek, daher gibt es keine Garantie, dass es auf alle Compiler auf die gleiche Weise funktioniert. Sie werden feststellen, dass es bei einigen Compilern absolut nichts Besonderes ist. Dies ist jedoch eine bessere Wahl, da not_null alle Compilervariationen umbrechen kann, um das gleiche Ergebnis zu erzielen (auch die Laufzeitprüfung kann hinzugefügt werden). Aber nach der aktuellen Implementierung (siehe Link) gibt es nur Unterstützung für Microsoft Compiler mit __assume (konnte nicht finden Implementierungen für gcc, aber wenn Sie eine haben, dann ist es ein Vorteil, es zu verwenden)

+0

gsl :: not_null verwendet die Funktionen von GCC und Clang ähnlich wie MSVCs __assume jetzt. OTOH, das ist * nicht * identisch mit dem Ergebnis, das durch das nonnull-Attribut erreicht wird - ersteres ist nur ein Hinweis, letzteres ist eine Garantie. –