2016-09-14 12 views
9

Eine externe Bibliothek wir enthält die folgenden expliziten Konstruktor verwenden:Wird "Explizit" von einem Konstruktor binärkompatibel entfernt?

class Chart { 
public: 
    explicit Chart(Chart::Type type, Object *parent); 
    // ... 
}; 

Der Compiler mit der folgenden Warnung klagt:

chart.h: warning #2305: declaration of 'explicit' constructor 
without a single argument is redundant 

Ist es binärkompatibel zu entfernen Sie einfach das Stichwort explicit in chart.h ohne die Bibliothek neu zu kompilieren, um die Warnung zu vermeiden? Mein Gefühl ist, dass es sicher ist, da explicit in diesem Fall sowieso keinen Sinn macht. Kann jemand bestätigen?

+5

Deaktivieren Sie dumme Warnungen. –

+0

Ich denke, das ist der beste Ratschlag :-) – dhaumann

+0

Die Warnung verwendet, um vor-C++ 11 perfekten Sinn zu machen. Wenn Ihr Compiler vor C++ 11 ist, können Sie auf ernstere Probleme mit C++ 11-Code stoßen, daher sollten Sie ein Upgrade in Betracht ziehen. –

Antwort

9

Ihre beste Wette bei einer Ländermeile ist, diese Warnung für die Dauer dieser Aufnahme auszuschalten, wenn Sie meine Bedeutung verstehen. Do not hacken Sie den Verkäufer-Code.

Die Verwendung von explicit für Konstruktoren mit mehreren Argumenten ist in C++ 11 und höher sinnvoll, da damit die implizite Klammerinitialisierung beendet werden kann. Futhermore die Standard nicht sagen, dass explicit Entfernen des Layout der Klasse bewahren müssen, so müssen Sie davon ausgehen, dass explicitkönnte brechen Binärkompatibilität zu entfernen. Auch das Löschen könnte das Verhalten der erfundenen SFINAE-Muster ändern, da dieser Konstruktor unter bestimmten Umständen wieder verfügbar sein könnte. Siehe http://en.cppreference.com/w/cpp/language/sfinae.

2

explicit macht Sinn, mit mehreren Parametern im Zusammenhang mit den Klammer-Initialisierungen in C++ 11 und höher:

void foo(Chart const &); 

// ... 

// Will only compile without `explicit` 
foo({Chart::Type::pie, myObj}); 

Ob binärkompatibel ist letztlich zu entfernen explicit auf Ihrem Compiler ab, so dass Sie‘ Ich muss das in seiner Dokumentation finden.

Da explicit jedoch eine High-Level-Sprachfunktion ist, die nur die Übersteuerungsauflösung steuert, würde ich nicht erwarten, dass sie die Kompatibilität unterbricht, solange sie nicht die beste Übereinstimmung für einen bereits bestehenden Anruf ändert , einschließlich in jedem Code, den Sie aus der Bibliothek selbst kompilieren (Vorlagen und/oder Inline-Funktionen).

Das heißt, das ist reine Ad-hoc-Patching: nach dem Standard, so dass Sie direkt in UB Gebiet schleudert. Zitat von n.m.:

Fummeln mit Kopfzeilen wie das bricht ODR. Die Binärdateien des Herstellers werden mit einer bestimmten Definition einer Klasse kompiliert, Ihre Binärdateien werden mit einer anderen Definition derselben Klasse kompiliert. Das ist illegal. Es spielt keine Rolle, wie klein die Änderung ist. Die Definitionen müssen Token für Token identisch sein, Periode.

ich einfach empfehlen würde, um die Warnung in diesem Header zu Schweigen, indem man sich in #pragma s Einwickeln wo enthalten (oder in einem Header benutzerdefinierten Proxy und umfasst das).

+0

UV'd.Aber was "Ob es binär kompatibel ist, um explizit zu entfernen, hängt letztlich von Ihrem Compiler ab, also müssten Sie das in seiner Dokumentation finden." wir sind hier im Widerspruch. Nach meinem Verständnis darf 'explizit' das 'struct'-Layout nicht beeinflussen. Könnte aber falsch sein. – Bathsheba

+1

@Bathsheba über das Layout, das ich nicht weiß, aber "Explizit" könnte zum Beispiel an Namensmangel teilnehmen, und ändern Sie den Namen des Konstruktors Prozedur. Ich gebe zu, es ist ein bisschen schwierig für mich zu sagen, dass nichts garantiert ist, ohne den ganzen Standard gelesen zu haben, aber ich bezweifle, dass es einen Abschnitt darüber gibt, also ... Sicherheit zuerst! – Quentin

+5

@Batsheba Fiedeln mit solchen Headern bricht ODR. Die Binärdateien des Herstellers werden mit einer bestimmten Definition einer Klasse kompiliert, Ihre Binärdateien werden mit einer anderen Definition derselben Klasse kompiliert. Das ist illegal. Es spielt keine Rolle, wie klein die Änderung ist. Die Definitionen müssen Token für Token identisch sein, Periode. Der Compiler kann nach allem, was wir kennen, einen Hash der Definition in Symbolnamen enthalten. –

Verwandte Themen