Ich habe ein Projekt, das streng in C ++ 14 geschrieben ist, und ich möchte es in einem anderen Projekt verwenden, das C ++ 17 ist. Einige der C ++ 14-Funktionen wie Dynamic Exception Specification wurden in C entfernt ++ 17.

Gibt es eine Möglichkeit, beide Codebasen zusammen zu verwenden und zu kompilieren? Das Projekt ist groß genug, um Refactoring unpraktisch zu machen.

c++
3
Ghasem Ramezani 19 Aug. 2020 im 19:30

2 Antworten

Beste Antwort

Dies ist plattformspezifisch: Es ist denkbar, dass wesentlich unterschiedliche Header gemäß dem in der Befehlszeile angegebenen Standard usw. ausgewählt werden.

Das heißt, hier ist eine Antwort von Jonathan Wakely, die Ihnen versichert, dass es mit gcc kein solches Problem geben sollte. wenn Sie sich von instabilen Funktionen in alten Compilern fernhalten.

Der zugrunde liegende Grund laut Jonathan ist, dass C ++ - Standardimplementierungen in gcc, sobald sie als stabil deklariert wurden, ihren ABI (d. H. Nach außen gerichtete Typdefinitionen, Namensverfälschung) nicht mit dem ausgewählten C ++ - Standard ändern, auch nicht zwischen Compilerversionen.

Da alle Interaktionen zwischen den Übersetzungseinheiten auf die kleinste gemeinsame Standardversion beschränkt sein müssen, gibt es kein Problem: Die C ++ 11-Funktionen ändern sich nicht, wenn Sie C ++ 17 angeben. Neuere Funktionen in den C ++ 17-TUs können nicht für die Kommunikation mit früheren Standard-TUs verwendet werden, da sie noch nicht verfügbar waren, daher auch dort kein Problem. Wenn Sie in der Lage sind, neu zu kompilieren, wäre der sicherste Rat:

  1. Verwenden Sie am besten dieselben std :: string-Versionen (die zur Kompilierungszeit über die Befehlszeile gesteuert werden können).
  2. Verwenden Sie das gleiche libstdc ++.
  3. Verwenden Sie dieselbe gcc-Version (und steuern Sie den für jede TU verwendeten Sprachstandard über die Befehlszeile).

Für andere Compiler wäre es sinnvoll, eine ähnliche Kompatibilitätsstrategie zu verfolgen.

1
Peter - Reinstate Monica 19 Aug. 2020 im 17:51

Ja, Sie können die C ++ - Version erkennen und unter bestimmten Bedingungen kompilieren:

void foo() {
#if __cplusplus >= 201703L
    // code written for C++17 goes here
#else
    // code written for C++14 goes here
#endif
}

Die vollständige Liste der __cplusplus Makros lautet wie folgt:

#if __cplusplus >= 199711L // C++98
#if __cplusplus >= 201103L // C++11
#if __cplusplus >= 201402L // C++14
#if __cplusplus >= 201703L // C++17
#if __cplusplus >= 202002L // C++20

Beachten Sie, dass dies verschiedene Probleme verursacht:

  • Es ist unmöglich, Code wie diesen zu testen, wenn Sie Ihre Tests für C ++ 14 und C ++ 17 nicht separat kompilieren
  • Ihre IDE zeigt möglicherweise nicht einmal Warnungen oder Fehler in entfernten vorverarbeiteten Blöcken an
  • Sie müssen zwei separate Versionen desselben Codes verwalten

Wenn Sie können, finden Sie eine Lösung, die in beiden Versionen funktioniert, oder verwenden Sie mindestens so wenige Blöcke wie möglich. Wenn Sie nur ein einzelnes Schlüsselwort entfernen möchten, ziehen Sie die folgende Lösung in Betracht:

#if __cplusplus >= 201703L // C++17
#define THROWS(exception) noexcept(false)
#else
#define THROWS(exception) throw(exception)
#endif

// now you can use it like this in both C++14 and C++17:
void fun() THROWS(MyException);
0
Jan Schultke 19 Aug. 2020 im 17:18