我正在尝试在Windows上构建我的矿山项目,这对我来说是第一次。我是该平台的初学者。我正在使用clang-cl支持C11。源最初使用noreturn
中的<stdnoreturn.h>
来注释永远不会返回的函数。我在编译时遇到了一堆declspec错误,然后将其缩小到尽可能小的文件范围。
#include <stdnoreturn.h>
#include <stdlib.h>
无论是靠自己建造,还是靠在一起 produce a laundry list of errors,所有类型完全相同:
__declspec attributes must be an identifier or string literal
所有这些对象都对同一宏扩展上的变化不满意:
[build] C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\vcruntime.h(326,20): error: __declspec attributes must be an identifier or string literal
[build] __declspec(noreturn) void __cdecl __report_gsfailure(_In_ uintptr_t _StackCookie);
[build] ^
[build] C:\PROGRA~1\LLVM\lib\clang\8.0.1\include\stdnoreturn.h(27,18): note: expanded from macro 'noreturn'
[build] #define noreturn _Noreturn
我尝试将-fms-extensions和-fms-compatibility传递给clang-cl,但没有骰子。我最好的猜测是,当Windows在该declspec中放入关键字时,会感到lang恼吗?我对任何MS扩展都不了解。
使用普通的旧_Noreturn
可以很好地工作,因此我可以编译我的代码。但是,还有人对这里发生的事情以及解决方法有更多的了解吗?是将msvc和clang结合在一起只是固有的麻烦,还是我做错了什么?
编辑:我是个白痴。
问题是宏扩展正在Windows SDK标头中破坏_declspec(noreturn)
。解决方案很明显:
#include <stdlib.h>
#include <stdnoreturn.h>
哪种构建都很好,因为宏是在使用declspec(noreturn)
答案 0 :(得分:2)
我已经在编辑中发布了答案,但是为了结束问题,我将在此处发布扩展版本。
问题来自C11标准和Windows特定的C / C ++扩展之间的冲突。 Windows使用早于C11的declspec syntax扩展了存储类。它为不以__declspec(noreturn)
返回的函数提供了一个存储类。
不幸的是,这与C11中的关键字宏noreturn
冲突。微软可能不会认为这是一个问题,因为他们没有要求任何对C11的支持。如果您尝试通过定义的宏使用Windows SDK标头,则编译器将抱怨通过原始问题中列出的有点神秘的错误消息在declspec中使用关键字(noreturn
扩展为_Noreturn
,在C11中添加了实际关键字)。
尽管答案很简单:只要您的代码不尝试将__declspec(noreturn)
和noreturn
混合使用,这将是多余的,只需在另一个后面加上<stdnoreturn.h>
标头系统标题。预处理程序不会在Windows SDK标头中展开noreturn
,并且所有内容都会消失。