55 votes

Puis-je imiter un en-tête C qui redéfinit bool en C++?

Je suis en train d'écrire un programme, que je préférerais vraiment à écrire en C++, cependant, je suis tenu d'inclure un en-tête C qui redéfinit bool:

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

La solution évidente serait de modifier l'en-tête pour dire:

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

mais, hélas, puisque la bibliothèque est en lecture seule, je ne le peuvent pas.

Est il possible que je peux dire à gcc d'ignorer ce typedef? Ou, devrais-je écrire la plupart des fonctions en C++ et ensuite faire un wrapper C pour les deux? Ou, devrais-je le sucer et à écrire la chose en C?

75voto

Potatoswatter Points 70305

Vous pouvez pirater!

La bibliothèque, l'appellent fooLib, pense que c'est en utilisant un certain type bool dont il a la prérogative de définir. À la bibliothèque, bool n'est qu'un identifiant.

Ainsi, vous pouvez le forcer à utiliser un autre identifiant à la place:

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

Maintenant que le compilateur voit la ligne fautive transformé à ceci:

typedef int fooLib_bool;

Vous êtes coincé avec l'interface à l'aide de type fooLib_bool = int au lieu d'un réel bool, mais qui est impossible à contourner, comme le code peut en effet s'appuyer sur les propriétés de l' int, et de la bibliothèque binaire aurait été compilé avec une telle hypothèse cuit.

27voto

Marco A. Points 18535

Je suppose que vous pouvez envelopper le code malveillant dans un en-tête, puis le fnud ce que vous n'avez pas besoin

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"

Quant à la définition de type.. le compilateur doit se plaindre si vous essayez de redéfinir un type de base en C++. Vous pouvez redeclare un type par la voie (en C++) ou les définir (simple texte de remplacement).

21voto

Matthieu M. Points 101624

Malheureusement, non, vous ne pouvez pas utiliser ce fichier dans la Norme C++:

§7.1.3 [dcl.typedef]

6/ Dans une portée, une définition de type spécificateur ne doit pas être utilisé pour redéfinir le nom de n'importe quel type déclaré dans le champ d'application de la référer à un type différent.

Ainsi, typedef ... bool; est interdite.

§17.6.4.3.1 [macro.noms]

2/ Une unité de traduction n' #define ou #undef noms lexicalement identiques pour les mots clés, les identifiants énumérés dans le Tableau 3, ou à l'attribut jetons décrit dans 7.6.

Et dans le §2.12 [lex.key] nous constatons que bool est un mot-clé.

Donc d'essayer de tromper le compilateur en utilisant #define bool ... avant d'inclure le fichier avi est interdit.


Alors, quelle est l'alternative ? Une cale d'épaisseur !

Isoler que les délinquance de la bibliothèque derrière un C & C++ compatible en-tête de votre propre; et la compilation de cette partie C. Ensuite, vous pouvez ajouter votre propre en-tête dans le programme C++ sans problème ou des astuces.

Note: oui, la plupart des compilateurs acceptent probablement #define bool ..., mais il est toujours explicitement interdite par la Norme.

11voto

user3277268 Points 159

Vous pouvez copier une mauvaise tête et utiliser une copie modifiée. Dire au compilateur le chemin qu'il doit préférer et...

8voto

Christian Hackl Points 4763

Vous pouvez compiler le code qui utilise l'en-tête (C, puis il suffit de le lier avec votre objet C++ fichiers. Vous utilisez probablement MSVC ou GCC; les deux peuvent compiler du code C++ ou C, et va vous permettre de créer compatible fichiers de l'objet.

Si c'est une solution propre ou inutiles overkill dépend vraiment de la situation exacte.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X