C99非空数组参数语法的MSVC兼容方案及跨编译器宏实现问询
跨编译器的非空指针参数注解方案
问题说明
这段代码:
int swap(int a[static 1], int b[static 1]) { ... }
能在GCC、Clang和ICX正常编译,但MSVC不支持数组参数里的static关键字(感谢@Davilsor的信息)。GNU系的__attribute__((nonnull))可以被GCC、Clang和Intel编译器识别,想知道MSVC有没有对应的机制,以及怎么写一个4款编译器都能用的通用宏。
解答
MSVC的等效非空注解
MSVC里对应nonnull的是__notnull关键字(C环境下),C++场景也可使用_Nonnull,作用都是告知编译器该指针参数不可为NULL,辅助编译器做优化和静态检查。
通用可移植宏
通过编译器预定义宏做分支判断,就能写出跨编译器的兼容宏:
// 定义跨编译器的非空参数注解宏 #if defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER) #define NONNULL(...) __attribute__((nonnull(__VA_ARGS__))) #elif defined(_MSC_VER) #define NONNULL(...) __notnull(__VA_ARGS__) #else #define NONNULL(...) /* 无支持时为空,不影响编译 */ #endif
使用方式
由于C语言中数组参数会自动退化为指针,static 1的核心诉求是限制指针非空,因此可以把数组写法换成指针形式,再用宏标记非空参数:
NONNULL(1, 2) int swap(int *a, int *b) { ... }
这样处理后:
- GCC、Clang、ICX会将宏解析为
__attribute__((nonnull(1,2))) - MSVC会解析为
__notnull(1,2) - 其他编译器会忽略该宏,代码可正常编译
如果想保留数组写法也完全可行,效果和指针形式一致:
NONNULL(1, 2) int swap(int a[], int b[]) { ... }
内容的提问来源于stack exchange,提问作者Madagascar
相关产品推荐
相关产品推荐

