Я пишу программу, и я действительно предпочел бы писать на 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 для двух? Или я должен смириться с этим и написать вещь на С?
Вы можете взломать это!
Библиотека, назовите это 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
main.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 [macro.names]
2 / Переводчик не должен
#define
или же#undef
имена, лексически идентичные ключевым словам, идентификаторам, перечисленным в таблице 3, или атрибутам-токенам, описанным в 7.6.
И в §2.12 [lex.key] мы находим, что bool
это ключевое слово.
Таким образом, пытаясь обмануть компилятор с помощью #define bool ...
до включения оскорбительного файла запрещено.
Итак, какова альтернатива? Как он !
Изолировать эту оскорбительную библиотеку за C & C ++ совместимый собственный заголовок; и скомпилируйте эту часть как C. Затем вы можете включить свой собственный заголовок в программу C ++ без проблем и уловок.
Примечание: да, большинство компиляторов, вероятно, примут #define bool ...
, но это все еще явно запрещено Стандартом.
Вы можете скопировать неверный заголовок и использовать отредактированную копию. Скажите компилятору путь, который он должен предпочесть и …
Вы можете скомпилировать код, который использует заголовок как C, а затем просто связать его вместе с вашими объектными файлами C ++. Вы, вероятно, используете MSVC или GCC; оба могут компилировать код как C ++ или C и позволят вам создавать совместимые объектные файлы.
Является ли это чистым решением или ненужным лишним убийством, действительно зависит от конкретной ситуации.