Могу ли я имитировать заголовок 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 для двух? Или я должен смириться с этим и написать вещь на С?

55

Решение

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

Библиотека, назовите это 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и бинарный файл библиотеки был бы скомпилирован с таким допущением.

75

Другие решения

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

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 ++) или определить его (простая замена текста).

27

К сожалению, нет, вы не можете использовать этот файл в стандарте 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 ..., но это все еще явно запрещено Стандартом.

21

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

11

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

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

8
По вопросам рекламы [email protected]