2015-09-22 13 views
6

Folgende Code kompiliert gut ohne Warnungen (mit Standardoptionen zu g ++). Gibt es eine Flagge, mit der wir g ++ bitten können, in solchen Fällen Warnungen auszugeben?Durchsetzung Typ Sicherheit beim Casting char * zu bool in C++ 11

void foo(bool v) { 
} 

void bar() { 
    foo("test"); 
} 
+1

Versuchen Sie '-Wimplicit' –

+0

Es ist nicht nur für Zeichenliterale und Zeiger auf Zeichen, die davon betroffen sind, aber * alle * Zeiger sind implizit in' bool' umwandelbar. –

+3

Wenn * ein Raw-String-Literal als Argument * ist das einzige Problem, das Sie hinzufügen können ein 'void foo (const char *) = löschen;' Überladung –

Antwort

3

Ich mag clang -Weverything versuchen und die Warnungen auswählen, die Pop-out:

void foo(bool) {} 

void bar() { 
    foo("test"); 
} 

void baz() { 
    foo(nullptr);  
} 

int main() {} 

main.cpp: 5: 7: Warnung: implizite Konvertierung schaltet Stringliteral in Bool: ‚const char [5] 'zu' bool '[-Wstring-Umwandlung] foo ("test");

main.cpp: 8: 9: Warnung: implizite Konvertierung der Nullptr-Konstante in 'bool' [-Wnull-Konvertierung] foo (nullptr);

Leider wird weder -Wstring-conversion noch -Wnull-conversion von g ++ unterstützt. Sie könnten versuchen, einen Funktionsanforderungs-/Fehlerbericht an gcc zu senden.

+2

* "Gibt es eine Flagge, die wir verwenden können **, um g ++ ** zu bitten, in solchen Fällen Warnungen auszugeben?" * –

+0

@PiotrSkotnicki Jetzt sind Sie mehr "pedantisch" als g ++! ... –

+2

@PiotrSkotnicki Ich benutze -Weverything um herauszufinden welche Warnung ausgelöst wird, leider wird diese nicht von g ++ unterstützt – TemplateRex

2

Wenn ich wirklich verhindern wollte, dass eine solche Funktion einen Zeiger übergeben würde, würde ich dies in C++ 11 tun;

void foo(bool); 
template<class T> void foo(T *) = delete; 

void bar() 
{ 
    foo("Hello"); 
} 

, die einen Compilerfehler auslösen wird.

Vor C++ 11 (nicht jeder kann aus verschiedenen Gründen aktualisieren) ist eine Technik;

void foo(bool); 
template<class T> void foo(T *); // note no definition 

void bar() 
{ 
    foo("Hello"); 
} 

und dann haben die Definition von foo(bool) irgendwo (in einer und nur einer Übersetzungseinheit in Ihrem Build). Für die meisten Toolchains, die einen traditionellen Compiler und Linker verwenden (was die meisten Toolchains in der Praxis sind, einschließlich der meisten Installationen von g ++), wird der Linker-Fehler durch foo<char const>(char const*) verursacht, der nicht definiert ist. Der genaue Wortlaut des Fehlers ist linkerabhängig.

Beachten Sie, dass die Fehler von einem Entwickler bewusst umgangen werden können. Aber solche Techniken werden die versehentliche Verwendung stoppen.

Wenn Sie zulassen möchten, dass ein Zeiger außer char const * übergeben wird, deklarieren Sie einfach void foo(const char *) wie oben und deklarieren Sie die Vorlage nicht.

+3

'= delete' ist besser, gibt Compiler statt Linker Fehler – TemplateRex

+0

Funktioniert das' = delete' aber mit einer Vorlage ? Nur fragen. –

+0

Besser hängt von der Perspektive ab. Nicht jeder kann auf C++ 11 aktualisieren. Wie auch immer, ich werde auf Referenz C++ 11 aktualisieren. – Peter