C静态内联函数重定义规则

时间:2011-06-23 01:04:54

标签: c function static shadow undefined-behavior

假设在bar.h可能存在:

static inline int fun () { return 2; }

并确保始终定义fun foo.h包含以下内容:

static inline int fun () { return 3; }

bar.h包含定义时,以下是否会引发未定义的行为?

#include "foo.h" /* ensure there is always a definition */
#include "bar.h" /* use the bar definition if it exists */

int main () {
   /* ... */
   int x = fun ();
   /* ... */

使用gcc(4.0.1)(旧版,但它是我目前的版本)行为符合预期 - 当缺少条形版本时使用foo版本,并且当条形图版本存在时使用条形图版本。

3 个答案:

答案 0 :(得分:9)

不,这是不允许的。 fun()的定义声明fun()具有内部链接(由于static),而C标准中的§6.9则表示:

  

不得超过一个   每个人的外部定义   用内部声明的标识符   翻译单位的联系。

违反“shall”子句是未定义的行为,这意味着程序的语义完全未定义,并且编译器不必发出错误消息。

答案 1 :(得分:3)

你不允许这样做,你的编译器不应该让你。

只有在所有定义相同的情况下(但每个TU从不超过一个定义),您才能拥有非静态内联函数的多个定义。对于头文件中定义的内联函数,这必然会发生。

对于静态链接,每个TU可以有不同的定义,但每个TU仍然只能有一个定义。

(对不起多次修改。)

答案 2 :(得分:1)

如果要达到相同的效果,可以使用无害的宏:

// foo.h - include guards omitted because of iPhone
#ifndef VALUE
# define VALUE 2
#endif

static inline int fun() { return VALUE; }

// bar.h
#define VALUE 3
#include "foo.h"

包含订单翻转,但它不如完整的宏版本吓人(这在所有恕我直言中都不可怕,但我不知道你/你的工作场所与宏的关系。)