编译器特定扩展
不同编译器提供特定扩展增强 C 语言功能。GCC 的 __attribute__、MSVC 的 __declspec、Clang 的各种扩展等。使用编译器扩展可以提高代码质量,但会降低可移植性。应在关键路径使用,并用条件编译隔离。
GCC 属性
/* 函数属性 */
__attribute__((noreturn)) void exit(int status);
__attribute__((const)) int square(int x); /* 纯函数,无副作用 */
__attribute__((malloc)) void *my_alloc(size_t n);
/* 变量属性 */
__attribute__((aligned(16))) int arr[4]; /* 16 字节对齐 */
/* 结构体属性 */
struct __attribute__((packed)) Header { /* 紧凑布局 */
char type;
int size;
};
分支预测提示
/* GCC */
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
if (likely(ptr != NULL)) { /* 大概率执行 */
/* ... */
}
if (unlikely(error)) { /* 小概率执行 */
/* ... */
}
内建函数
/* 字节序交换 */
uint32_t x = __builtin_bswap32(0x12345678); /* 0x78563412 */
/* 计算前导零 */
int zeros = __builtin_clz(16); /* 27(假设 32 位 int) */
/* 原子操作 */
int old = __sync_fetch_and_add(&counter, 1);
条件编译封装
#ifdef __GNUC__
#define NORETURN __attribute__((noreturn))
#define LIKELY(x) __builtin_expect(!!(x), 1)
#elif defined(_MSC_VER)
#define NORETURN __declspec(noreturn)
#define LIKELY(x) (x)
#else
#define NORETURN
#define LIKELY(x) (x)
#endif
NORETURN void fatal_error(const char *msg);
if (LIKELY(ptr != NULL)) {
/* ... */
}
常见错误
不加条件编译:
__attribute__((noreturn)) void func(void); /* GCC 特有,MSVC 编译失败 */
/* 正确 */
#ifdef __GNUC__
#define NORETURN __attribute__((noreturn))
#else
#define NORETURN
#endif
最佳实践
- 扩展功能用宏封装,提供默认实现
- 关键性能路径使用编译器扩展
- 公共接口保持标准 C 兼容
- 文档化使用的扩展和原因
- 持续集成测试多种编译器