含宏的内联函数在不同翻译单元中展开代码不同的行为判定
关于C语言inline函数与宏命名的几个问题
1. 自定义UNIQUE_NAME宏及跨翻译单元的行为分类
我定义了一个用于将__LINE__与前缀拼接的宏UNIQUE_NAME(PREFIX),代码如下:
#define CONCAT2_EXPAND(a, b) a ## b #define CONCAT2(a, b) CONCAT2_EXPAND(a, b) #define UNIQUE_NAME(prefix) CONCAT2(CONCAT2(prefix, _), __LINE__)
如果将该宏用于inline函数,且这个函数被包含到两个不同的翻译单元中,除非头文件完全一致,否则inline函数的展开代码会存在差异。请问这种行为属于已定义、未指定、实现定义还是未定义行为?
2. 代码评审反馈
我收到如下评审意见:
你现在进退两难。使用__LINE__并非良策,因为无法避免在同一行两次调用UNIQUE_NAME,此时生成的名称就不再唯一了。__COUNTER__能生成唯一名称,但又过于唯一:若UNIQUE_NAME用于inline函数并被包含在两个不同的翻译单元中,该inline函数的展开代码会在两个TU中存在差异,这属于未定义行为。——@Matthieu M.
3. static inline与inline函数的区别疑惑
我对在头文件中定义static inline函数和inline函数(并包含到不同.c文件中)的区别存在疑惑,示例代码如下:
static inline版本
[[gnu::always_inline]] static inline void foo(void) { bool UNIQUE_NAME(bar); // ... }
inline版本
inline void foo(void) { bool UNIQUE_NAME(bar); // ... }
我认为上述评审意见针对的是第二个inline函数,而非第一个static inline函数,这个判断是否正确?
内容的提问来源于stack exchange,提问作者Madagascar
相关产品推荐
相关产品推荐

