我正在尝试使用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无效”。为什么会发生这种情况,如何修改此行以使其编译?需要帮助
答案 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位指针转换为小于指针的整数类型(例如int
或bool
)通常是一个错误:您正在截断指针的值。此外,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位平台(int
和void*
都是32位)但是失败大多数64位平台(其中int
为32位,void*
为64位)。在这种情况下,使用指针大小的整数类型(例如int
或uintptr_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)
从指向不同大小的整数类型的指针中抑制强制转换的警告。