Могу ли я подражать заголовку C, который переопределяет bool в С++?
Я пишу программу, и я бы предпочел писать на С++, однако мне нужно включить заголовок 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?
Ответы
Ответ 1
Вы можете взломать его!
Библиотека, назовите ее 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
, а бинарный файл библиотеки будет иметь были скомпилированы с таким предположением, испеченным в.
Ответ 2
Я полагаю, вы можете обернуть код нарушения в заголовок, а затем отменить то, что вам не нужно
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.. компилятор должен жаловаться, если вы попытаетесь переопределить базовый тип в С++. Вы можете повторно использовать тип, кстати (разрешен в С++) или определить его (простая замена текста).
Ответ 3
К сожалению, нет, вы не можете использовать этот файл в стандартном С++:
§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. Затем вы можете включить свой собственный заголовок в программу на С++ без проблем или трюков.
Примечание: да, большинство компиляторов, вероятно, примет #define bool ...
, но стандарт по-прежнему явно запрещен.
Ответ 4
Вы можете скопировать плохой заголовок и использовать отредактированную копию. Сообщите компилятору путь, который он должен предпочесть и...
Ответ 5
Вы можете скомпилировать код, который использует заголовок как C, а затем просто связать его вместе с вашими объектными файлами С++. Вероятно, вы используете MSVC или GCC; оба могут компилировать код как С++ или C и позволят вам создавать совместимые объектные файлы.
Независимо от того, действительно ли чистое решение или излишний избыток зависит от конкретной ситуации.