本文介绍了constexpr和初始化一个静态const void指针与reinterpret转换,这是什么编译器是正确的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 请考虑下面的代码: struct foo { static constexpr const void * ptr = reinterpret_cast< const void *>(0x1); }; auto main() - > int { return 0;上面的例子在g ++ v4.9()中编译正确, http://coliru.stacked-crooked.com/a/90c872d2d3572488\">实例演示),但无法在clang v3.4(现场演示)并生成以下错误: 问题: 根据标准,哪两个编译器是正确的? 解决方案 TL; DR clang 是正确的,这是已知的 gcc 错误。你可以使用 intptr_t 而不是当你需要使用值或者如果这是不可行的然后两个 gcc 和 clang 支持一些文档化的工作,应该允许您的特定用例。 详细信息 所以 clang 在这一个上是正确的,如果我们去草案C ++ 11标准部分 5.19 段落 说:并包含以下项目:一个简单的解决方案是使用 intptr_t : static constexpr intptr_t ptr = 0x1; ,然后在需要使用时进行投放: reinterpret_cast< void *>(foo :: ptr); 这可能是诱人的,但这个故事更有趣。这是已知且仍然开放的 gcc 错误,请参阅 Bug 49171:[C ++ 0x] [constexpr]常量表达式支持reinterpret_cast 。从讨论中清楚的是, gcc devs有一些明确的用例:但无法获取针对这些用例的异常,请参阅关闭的问题1384 : 显然 gcc 和 clang 支持一个有点文件化的扩展,它允许使用 __ builtin_constant_p(exp),所以下面的表达式被 gcc 和 clang : static constexpr const void * ptr = __builtin_constant_p(reinterpret_cast< const void *> 0x1))? reinterpret_cast< const void *>(0x1):reinterpret_cast< const void *>(0x1); 查找文档几乎不可能,但这 llvm commit是信息性的,以下片段提供了一些有趣的阅读: > 和: //此宏强制其参数为常数折叠,即使它不是 //否则为常量表达式。 define fold(x)(__builtin_constant_p(x)?(x):(x)) 我们可以在gcc-patches电子邮件中找到这个功能的更正式的解释: C常量表达式,VLA等修复,它说: 表示完全折叠,而不考虑它是否是一个常量表达式Consider the following piece of code:struct foo { static constexpr const void* ptr = reinterpret_cast<const void*>(0x1);};auto main() -> int { return 0;}The above example compiles fine in g++ v4.9 (Live Demo), while it fails to compile in clang v3.4 (Live Demo) and generates the following error:Questions:Which of the two compilers is right according to the standard?What's the proper way of declaring an expression of such kind? 解决方案 TL;DRclang is correct, this is known gcc bug. You can either use intptr_t instead and cast when you need to use the value or if that is not workable then both gcc and clang support a little documented work-around that should allow your particular use case.DetailsSo clang is correct on this one if we go to the draft C++11 standard section 5.19 Constant expressions paragraph 2 says:and includes the following bullet:One simple solution would be to use intptr_t:static constexpr intptr_t ptr = 0x1;and then cast later on when you need to use it:reinterpret_cast<void*>(foo::ptr) ;It may be tempting to leave it at that but this story gets more interesting though. This is know and still open gcc bug see Bug 49171: [C++0x][constexpr] Constant expressions support reinterpret_cast. It is clear from the discussion that gcc devs have some clear use cases for this:but were not able to get an exception carved for these use cases, see closed issues 1384:BUT apparently gcc and clang support a little documented extension that allows constant folding of non-constant expressions using __builtin_constant_p (exp) and so the following expressions is accepted by both gcc and clang:static constexpr const void* ptr = __builtin_constant_p( reinterpret_cast<const void*>(0x1) ) ? reinterpret_cast<const void*>(0x1) : reinterpret_cast<const void*>(0x1) ;Finding documentation for this is near impossible but this llvm commit is informative with the following snippets provide for some interesting reading:and:and:We can find a more formal explanation of this feature in the gcc-patches email: C constant expressions, VLAs etc. fixes which says: 这篇关于constexpr和初始化一个静态const void指针与reinterpret转换,这是什么编译器是正确的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云! 08-19 18:39