Подтвердить что ты не робот

Могу ли я подражать заголовку 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?

4b9b3361

Ответ 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 и позволят вам создавать совместимые объектные файлы.

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