Kann ich einen C-Header nachahmen, der bool in C++ neu definiert?

Lesezeit: 5 Minuten

Benutzeravatar von L Co
L Co

Ich schreibe ein Programm und würde es wirklich vorziehen, in C++ zu schreiben, aber ich muss einen C-Header einfügen, der bool neu definiert:

# define false 0
# define true  1
typedef int bool;

Die offensichtliche Lösung wäre, den Header so zu bearbeiten, dass er sagt:

#ifndef __cplusplus
# define false 0
# define true  1
typedef int bool;
#endif

aber leider kann ich das nicht, da die Bibliothek schreibgeschützt ist.

Gibt es eine Möglichkeit, gcc anzuweisen, diese Typdefinition zu ignorieren? Oder kann ich die meisten Funktionen in C++ schreiben und dann einen C-Wrapper für die beiden erstellen? Oder sollte ich es aufsaugen und das Ding in C schreiben?

  • Wenn das so ist <stdbool.h>du kannst einfach #define das entsprechende Tag muss es sagen, dass es seine Arbeit bereits getan hat. Wenn es wie C ist, __bool_true_false_are_defined

    – Chris

    23. Februar 2014 um 9:09 Uhr


  • @chris <stdbool.h> sollte bereits eigene C++-Wächter haben

    – Erbureth

    23. Februar 2014 um 10:24 Uhr


  • Vielleicht hat dies etwas Nützliches: stackoverflow.com/questions/19377678/…

    – Nim

    23. Februar 2014 um 10:38 Uhr

  • @Erbureth, aber du würdest nicht wollen, dass es auch nur einmal passiert.

    – Chris

    23. Februar 2014 um 15:44 Uhr

  • @chris Ich meinte C++ Guards, nicht standardmäßige Guards

    – Erbureth

    3. September 2014 um 14:00 Uhr

Du kannst es hacken!

Die Bibliothek, nennen Sie es fooLibdenkt, es verwendet irgendeinen Typ bool die er bestimmen darf. Zur Bibliothek, bool ist nur eine Kennung.

Sie können es also einfach zwingen, stattdessen eine andere Kennung zu verwenden:

#define bool fooLib_bool
#include "fooLib.h"
#undef bool
#undef true
#undef false

Jetzt sieht der Compiler die fehlerhafte Zeile wie folgt umgewandelt:

typedef int fooLib_bool;

Sie stecken mit der Schnittstelle mit Typ fest fooLib_bool = int statt echt boolaber das lässt sich nicht umgehen, da sich der Code tatsächlich auf die Eigenschaften von stützen könnte intund die Bibliotheksbinärdatei wäre mit einer solchen Annahme kompiliert worden.

  • Das ist möglicherweise kein Problem, da die Bibliotheksbinärdatei sowieso int sieht und Sie ein in auf der Schnittstellenebene bereitstellen müssen (oder bool wird darauf gecastet).

    – Erbureth

    23. Februar 2014 um 10:22 Uhr


  • Genau genommen, #define <keyword> ... ist verboten. Ich nehme an, die meisten C++-Compiler werden es akzeptieren, aber sie hätten das Recht, sich zu weigern, das Programm zu kompilieren.

    – Matthias M.

    23. Februar 2014 um 12:17 Uhr

  • @MatthieuM., Nur wenn Sie einen Standardbibliotheksheader einfügen. Ich bin mir nicht sicher, wie das gelten würde, wenn das Makro da und weg ist Vor Alle Header sind enthalten.

    – Chris

    23. Februar 2014 um 15:49 Uhr

  • @chris: Ich hasse den C++-Standard. Ernsthaft. Ich habe noch nie ein anderes Dokument mit solch komplizierten Definitionen und Regeln gelesen. Jedes Mal, wenn Sie eine feste Regel (endlich!) finden, wird sie durch eine Formulierung an anderer Stelle gemildert. seufzen

    – Matthias M.

    23. Februar 2014 um 15:57 Uhr

  • @MatthieuM., dem kann ich zustimmen. Das macht es auf jeden Fall interessant. Ich habe das Gefühl, dass seine Komplexität mit den Gesetzen, nach denen wir leben, vergleichbar sein könnte.

    – Chris

    23. Februar 2014 um 15:59 Uhr

Benutzeravatar von Marco A
Marco A.

Ich nehme an, Sie können den anstößigen Code in einen Header packen und dann das, was Sie nicht brauchen, aufheben

Library_wrapper.h:

#define bool something_else // This will get you past the C++ compilation
#include "library.h"
#undef false
#undef true
#undef bool

main.cpp:

#include "Library_wrapper.h" 
#include "boost.h"

Hinsichtlich der Typdefinition sollte sich der Compiler beschweren, wenn Sie versuchen, einen Basistyp in C++ neu zu definieren. Sie können übrigens einen Typ umdeklarieren (ist in C++ erlaubt) oder definieren (einfache Textersetzung).

  • Wahrscheinlich ist die Typedef und nicht die #defines problematisch.

    – bvj

    23. Februar 2014 um 9:09 Uhr

  • In C++ können Sie Typedefs neu definieren, in C können Sie das nicht, also nehme ich an, dass eine Problemumgehung wie oben erforderlich wäre

    – Marco A.

    23. Februar 2014 um 9:11 Uhr

  • Ich habe Ihren ursprünglichen Beitrag kommentiert, der Ihre Bearbeitung zum Ändern der Typedef nicht enthielt.

    – bvj

    23. Februar 2014 um 9:12 Uhr

  • -1, typedef int int; ist nicht legal. Wo hast du das überhaupt her? Es ist eine ungültige Kombination aus Typbezeichnern und keinem Deklarator. Es scheint nicht einmal eine Lösung zu sein, sondern dupliziert nur das vorliegende Problem, das das ähnlich ungültige Konstrukt ist typedef int bool;.

    – Kartoffelklatsche

    23. Februar 2014 um 9:37 Uhr


  • „In C++ können Sie Typedefs neu definieren“ – Sie dürfen a wiederholen typedef Erklärung, um die Bedeutung nicht zu ändern. Sie verhalten sich wie Deklarationen, nicht als Definitionen, und es ist analog zur zweimaligen Deklaration eines Funktionsprototyps. “C you can’t” — die Regeln sind die gleichen wie in C.

    – Kartoffelklatsche

    23. Februar 2014 um 9:49 Uhr

Benutzeravatar von Matthieu M
Matthias M.

Leider nein, Sie können diese Datei nicht in Standard-C++ verwenden:

§7.1.3 [dcl.typedef]

6/ In einem bestimmten Bereich darf ein Typedef-Bezeichner nicht verwendet werden, um den Namen eines in diesem Bereich deklarierten Typs neu zu definieren, um auf einen anderen Typ zu verweisen.

Daher typedef ... bool; ist verboten.

§17.6.4.3.1 [macro.names]

2/ Eine Übersetzungseinheit nicht #define oder #undef Namen, die lexikalisch mit Schlüsselwörtern, mit den in Tabelle 3 aufgeführten Bezeichnern oder mit den in 7.6 beschriebenen Attribut-Token identisch sind.

Und in §2.12 [lex.key] wir glauben, dass bool ist ein Schlüsselwort.

Versuchen Sie also, den Compiler mit auszutricksen #define bool ... vor dem Einfügen der anstößigen Datei ist verboten.


Also, was ist die Alternative? Wie er !

Isolieren Sie diese störende Bibliothek hinter einem eigenen C- und C++-kompatiblen Header; und kompilieren Sie diesen Teil als C. Dann können Sie Ihren eigenen Header ohne Probleme oder Tricks in das C++-Programm einfügen.

Hinweis: Ja, die meisten Compiler werden wahrscheinlich akzeptieren #define bool ...aber es ist immer noch ausdrücklich durch den Standard verboten.

  • Hinweis: Es wurde mir darauf aufmerksam gemacht [macro.names] gilt anscheinend nur, wenn Sie einen Standardbibliothek-Header in die Übersetzungseinheit einfügen.

    – Matthias M.

    24. Februar 2014 um 7:57 Uhr

Benutzeravatar von user3277268
Benutzer3277268

Sie können einen fehlerhaften Header kopieren und eine bearbeitete Kopie verwenden. Teilen Sie dem Compiler den Pfad mit, den er bevorzugen soll, und …

Sie könnten den Code, der den Header als C verwendet, kompilieren und ihn dann einfach mit Ihren C++-Objektdateien verknüpfen. Sie verwenden wahrscheinlich MSVC oder GCC; beide können Code entweder als C++ oder C kompilieren und ermöglichen es Ihnen, kompatible Objektdateien zu erstellen.

Ob das eine saubere Lösung oder unnötiger Overkill ist, hängt wirklich von der genauen Situation ab.

1411670cookie-checkKann ich einen C-Header nachahmen, der bool in C++ neu definiert?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy