我可以模仿在C++中重新定义bool的C头吗?

L C*_* Co 55 c c++ typedef mixing

我正在编写一个程序,我更喜欢用C++编写,但是,我需要包含一个重新定义bool的C头:

# define false 0
# define true  1
typedef int bool;
Run Code Online (Sandbox Code Playgroud)

显而易见的解决方案是编辑标题来说:

#ifndef __cplusplus
# define false 0
# define true  1
typedef int bool;
#endif
Run Code Online (Sandbox Code Playgroud)

但是,唉,因为图书馆是只读的我不能.

有没有办法告诉gcc忽略这个typedef?或者,我可以用C++编写大多数函数,然后为这两个函数创建一个C包装器吗?或者,我应该把它吸干并用C写出来吗?

Pot*_*ter 75

你可以破解它!

该库称之为fooLib认为它正在使用某种类型bool,它具有定义的特权.到图书馆,bool只是一个标识符.

因此,您可以强制它使用另一个标识符:

#define bool fooLib_bool
#include "fooLib.h"
#undef bool
#undef true
#undef false
Run Code Online (Sandbox Code Playgroud)

现在,编译器将违规行转换为:

typedef int fooLib_bool;
Run Code Online (Sandbox Code Playgroud)

你使用类型fooLib_bool = int而不是真实的接口bool,但这是不可能解决的,因为代码实际上可能依赖于属性int,并且库二进制文件将被编译为这样的假设.

  • 严格来说,禁止使用`#define <keyword> ...`.我想大多数C++编译器都会接受它,但是他们有权拒绝编译程序. (6认同)
  • @MatthieuM.,[只有包含标准库标题.](http://stackoverflow.com/questions/2726204/c-preprocessor-define-ing-a-keyword-is-it-standards-conforming)我'我不太确定如果宏在那里并且在*包括任何标题之前全部*已经适用. (4认同)
  • @MatthieuM.,我同意这一点.这当然让它变得有趣.我觉得它的复杂性可以与我们生活的法则相媲美. (3认同)
  • @chris:我讨厌C++标准.认真.我从未阅读过任何其他具有如此错综复杂的定义和规则的文件.每当你找到一个硬盘规则(最后!)时,它会被其他地方的一些措辞所缓解.*叹* (2认同)

Mar*_* A. 27

我想你可以将有问题的代码包装成一个标题,然后取消你不需要的东西

Library_wrapper.h:

#define bool something_else // This will get you past the C++ compilation
#include "library.h"
#undef false
#undef true
#undef bool
Run Code Online (Sandbox Code Playgroud)

main.cpp中:

#include "Library_wrapper.h" 
#include "boost.h"
Run Code Online (Sandbox Code Playgroud)

关于typedef ..如果你尝试在C++中重新定义基本类型,编译器应该抱怨.您可以按顺序重新声明类型(在C++中允许)或定义它(简单文本替换).


Mat*_* M. 21

不幸的是,不,你不能在标准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 ...,但标准仍明确禁止.


use*_*268 11

您可以复制错误的标题并使用编辑过的副本.告诉编译器它应该更喜欢的路径和...


Chr*_*ckl 8

您可以编译使用标头为C的代码,然后将它与C++对象文件链接在一起.你可能使用MSVC或GCC; 两者都可以将代码编译为C++或C,并允许您创建兼容的目标文件.

这是一个干净的解决方案还是不必要的矫枉过正,取决于确切的情况.