我正试图在Windows上得到一个我的建筑项目,这对我来说是第一次。我是这个平台的初学者。我使用clang支持C11。源最初使用noreturn从<stdnoreturn.h>对永远不会返回的函数进行注释。在编译过程中,我遇到了一大堆解密规范错误,并尽可能地将其缩小到一个琐碎的文件。
#include <stdnoreturn.h>
#include <stdlib.h>无论是在自己的构建上还是在一起,它们都是生成一个错误列表,所有这些类型都是完全相同的:
__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-扩展和-fms-兼容clang,但没有得到骰子。我最好的猜测是,clang对Windows在解密规范中添加关键字感到不安吗?我对任何MS扩展不太了解。
使用普通的旧_Noreturn很好,所以我可以编译我的代码。但是,有没有人对这里发生的事情和解决办法有更深入的了解?合并msvc和clang只是天生的简陋,还是我做错了什么?
编辑:我是个白痴。
问题是宏扩展正在破坏Windows中的_declspec(noreturn)。解决办法显而易见:
#include <stdlib.h>
#include <stdnoreturn.h>,因为宏是在使用declspec(noreturn)的Windows报头之后定义的。
发布于 2019-08-05 22:47:59
我已经在编辑中发布了答案,但是为了结束这个问题,我将在这里发布一个扩展版本。
这个问题来自于C11标准和特定于Windows的C/C++扩展之间的冲突。Windows使用早于解密语法的C11扩展存储类。它为不随__declspec(noreturn)返回的函数提供了一个存储类。
不幸的是,这与来自C11的关键字宏C11冲突。微软可能并不认为这是一个问题,因为他们没有声称任何支持C11。如果您尝试使用带有宏定义的Windows标头,编译器将通过原始问题中列出的有点神秘的错误消息(noreturn扩展为_Noreturn,在C11中添加的实际关键字)抱怨在解密规范中使用关键字。
但答案很简单:只要您的代码不试图混合__declspec(noreturn)和noreturn (这将是多余的),只需在其他系统头之后包含<stdnoreturn.h>头即可。预处理器不会在Windows中展开noreturn,而且一切都是复制的。
https://stackoverflow.com/questions/57337834
复制相似问题