Могу ли я имитировать заголовок C, который переопределяет bool в C++?


Я пишу программу, и я бы действительно предпочел писать на C++, однако, я должен включить заголовок C, который переопределяет bool:

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

очевидным решением было бы изменить заголовок, чтобы сказать:

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

но, увы, так как библиотека только для чтения я не могу.

есть ли способ, которым я могу сказать gcc игнорировать этот typedef? Или я могу написать большинство функций на C++, а затем сделать оболочку C для двух? Или, я должен сосать его и написать вещь в C?

5 55

5 ответов:

вы можете взломать его!

библиотека, назовем ее fooLib, думает, что он использует что-то типа bool который он имеет прерогативу определить. В библиотеку, bool - это просто идентификатор.

Итак, вы можете просто заставить его использовать другой идентификатор:

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

теперь компилятор видит оскорбительную строку, преобразованную в это:

typedef int fooLib_bool;

вы застряли с интерфейсом, используя тип fooLib_bool = int вместо bool, но это невозможно обойти, как код может на самом деле полагаться на свойства int, и двоичный файл библиотеки был бы скомпилирован с таким предположением.

Я полагаю, вы можете обернуть оскорбительный код в заголовок, а затем отменить то, что вам не нужно

Library_wrapper.h:

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

главная.cpp:

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

относительно typedef.. компилятор должен жаловаться, если вы попытаетесь переопределить базовый тип в C++. Вы можете объявить тип кстати (это разрешено в C++) или определить его (простая замена текста).

к сожалению, нет, вы не можете использовать этот файл в стандартный C++:

§7.1.3 [dcl.typedef]

6/ в данной области спецификатор typedef не должен использоваться для переопределения имени любого типа, объявленного в этой области, для ссылки на другой тип.

typedef ... bool; запрещено.

§17.6.4.3.1 [макро.имена]

2/ A единица перевода не должна #define или #undef имена лексически идентичны ключевым словам, идентификаторам, перечисленным в таблице 3, или атрибутивным токенам, описанным в 7.6.

и §2.12 [lex.ключ] мы находим, что bool - ключевое слово.

таким образом, пытаясь обмануть компилятор с помощью #define bool ... до включения этого файла запрещено.


Итак, какова альтернатива ? Прокладка !

изолировать оскорбительная библиотека за вашим собственным заголовком, совместимым с C & C++; и скомпилируйте эту часть как C. Затем вы можете включить свой собственный заголовок в программу C++ без проблем или трюков.

Примечание: да, большинство компиляторов, вероятно, примут #define bool ..., но это все еще явно запрещено стандартом.

вы можете скопировать плохой заголовок и использовать отредактированную копию. Скажите компилятору путь, который он должен предпочесть и...

вы можете скомпилировать код, который использует заголовок как C, а затем просто связать его вместе с вашими объектными файлами C++. Вы, вероятно, используете MSVC или GCC; оба могут компилировать код как C++ или C и позволят вам создавать совместимые объектные файлы.

будет ли это правильное решение или ненужным излишеством действительно зависит от конкретной ситуации.