Clang中C语言空结构体是否触发UB?能否区分GCC与Clang行为?
空结构体:GCC与Clang的行为差异及区分方法
C标准(C99及后续版本)明确规定,无任何成员的结构体属于未定义行为,因为结构体必须至少包含一个成员。不过GCC和Clang都提供了对空结构体的扩展支持,但二者的行为存在可观测的差异,足以用来区分编译器。
区分编译器的示例代码
以下程序通过空结构体的大小差异即可区分GCC和Clang:
#include <stdio.h> struct empty {}; int main(void) { switch (sizeof(struct empty)) { case 0: puts("Compiled with GCC"); break; case 1: puts("Compiled with Clang"); break; default: puts("Unknown compiler"); } return 0; }
行为细节
- GCC:作为GNU扩展,空结构体的大小被定义为0,因此编译运行后会输出
Compiled with GCC。 - Clang:同样支持空结构体扩展,但默认会给空结构体分配1字节的存储空间(避免多个空结构体实例指针指向同一地址的潜在问题),所以运行后输出
Compiled with Clang。
额外说明
Clang确实支持空结构体,只是相关扩展的文档描述不如GCC详尽。如果给Clang添加-fms-extensions编译选项,空结构体的大小会变为0,与GCC行为一致,但这属于特定场景下的调整。
内容的提问来源于stack exchange,提问作者Kirill Afentev
相关产品推荐
相关产品推荐

