如何从bool转为void *?

时间:2009-03-03 15:04:45

标签: c++ type-conversion

我正在尝试使用mingw在Windows上为gtkmm构建cairomm。编译在函数调用中断,该函数调用具有将bool的reinterpret_cast重置为void *的参数。

cairo_font_face_set_user_data(cobj(), &USER_DATA_KEY_DEFAULT_TEXT_TO_GLYPHS, reinterpret_cast<void*>(true), NULL);

这是代码中断的地方,原因是“从bool到void *的reinterpret_cast无效”。为什么会发生这种情况,如何修改此行以使其编译?需要帮助

7 个答案:

答案 0 :(得分:13)

我看到这是用户数据,你可以控制对值的处理,首先将bool强制转换为int:reinterpret_cast<void *> (static_cast<int> (true))。这样做有意义,因为void *参数取代了此ANSI-C库中的模板函数。您所需要的只是一个真/假值。因此,只要将其作为指针进行临时编码就不存在危险。真的,你最好用这个:reinterpret_cast<void *> (1)reinterpret_cast<void *> (+true)

答案 1 :(得分:3)

根据标准,它看起来应该有效。第3.9.1-7节说bool是一个整数类型,5.2.10-5表示可以使用reinterpret_cast将整数类型的值显式转换为指针。您的编译器似乎不是完全标准的。

你能否将“真实”改为1?在整数和指针类型之间进行转换在C语言中是一个古老而不光彩的传统,因此C ++也是如此,如果找到一个不会这样做的编译器,那将是令人惊讶的。

或者,如果你真的必须这样做,请尝试(void *)true。然后洗手。

答案 2 :(得分:1)

reinterpret_cast是bad idea。告诉我们更多关于你要解决的问题,也许我们会找到一个解决方案而不需要重新解释。为什么要将bool转换为void *?

答案 3 :(得分:1)

我抱怨的唯一编译器是GCC(MinGW with GCC 3.4.5) - 我不知道为什么。该标准似乎清楚地表明这是允许的:

  

3.9.1基本类型

     

...

     

类型bool,char,wchar_t和   有符号和无符号整数类型   统称为整体类型。

     

5.2.10重新解释演员:

     

...

     

整数类型的值或   枚举类型可以是显式的   转换为指针。

尽管如此,使用reinterpret_cast<void *> (static_cast<int> (true))reinterpret_cast<void *> (1)的{​​{3}}是合理的解决方法。

答案 4 :(得分:0)

它失败了,因为强制转换是没有意义的 - 你正在取一个布尔值true / false值,并要求compilre把它解释为一个指针,这个指针是一个内存位置。这两个人甚至没有远程相关。

答案 5 :(得分:0)

尝试更新版本的编译器。我刚测试过,这个演员至少在gcc 4.1及以上版本上工作。我不知道gcc版本究竟是如何映射到mingw版本的。

答案 6 :(得分:0)

在某些情况下,非常希望编译器对reinterpret_cast<void*>(true)之类的代码发出警告或错误,即使此代码显然是合法的C ++。例如,它有助于移植到64位平台。

将64位指针转换为小于指针的整数类型(例如intbool)通常是一个错误:您正在截断指针的值。此外,C ++规范似乎并不能保证您可以直接将指针转换为较小的整数类型(强调添加):

  

5.2.10.4。指针可以显式转换为任何整数类型,足以容纳它。映射函数是实现定义的。

同样,将较小的整数类型转换为64位指针(与reinterpret_cast<void*>(true)一样)通常也是一个错误:编译器必须用某些东西填充指针的高位;它是零填充还是符号扩展?除非您正在编写用于内存映射I / O访问或DMA的低级平台特定代码,否则通常不希望这样做,除非您正在做一些hacky(比如将布尔值填充到指针中) )。但是C ++规范似乎并没有多说这个案例,除了它是实现定义的(脚注省略):

  

5.2.10.5。可以将整数类型或枚举类型的值显式转换为指针。*

     

转换为足够大小的整数的指针(如果实现上存在任何此类)并返回相同的指针类型将具有其原始值;指针和整数之间的映射在其他方面是实现定义的。

@monjardin建议reinterpret_cast<void*>(static_cast<int>(true))。如果错误的起源是整数类型的大小与指针大小不匹配,那么这将适用于大多数32位平台(intvoid*都是32位)但是失败大多数64位平台(其中int为32位,void*为64位)。在这种情况下,使用指针大小的整数类型(例如intuintptr_t(在Windows上)替换此表达式中的DWORD_PTR应该有效,因为bool和指针之间的转换允许使用大小的整数,指针大小的整数和指针之间的转换也是如此。

GCC的更高版本具有以下warning suppression options,但not for C++

  

-Wno-int-to-pointer-cast(仅限C和Objective-C)
  禁止从强制转换为不同大小的整数的指针类型发出警告。

     

-Wno-pointer-to-int-cast(仅限C和Objective-C)
  从指向不同大小的整数类型的指针中抑制强制转换的警告。