【发布时间】:2014-12-24 13:26:26
【问题描述】:
这段代码会导致未定义的行为吗?
header.h
#ifdef __cplusplus
extern "C"
{
#endif
inline int foo(int a)
{
return a * 2;
}
#ifdef __cplusplus
}
#endif
def.c
#include "header.h"
extern inline int foo(int a);
use.c
#include "header.h"
int bar(int a)
{
return foo(a + 3);
}
main.cpp
#include <stdio.h>
#include "header.h"
extern "C"
{
int bar(int a);
}
int main(int argc, char** argv)
{
printf("%d\n", foo(argc));
printf("%d\n", bar(argc));
}
这是一个在 C 和 C++ 中都必须使用 inline 函数的程序示例。如果 def.c 被删除并且 foo 没有在 C 中使用,它会起作用吗? (这里假设 C 编译器是 C99。)
此代码在编译时有效:
gcc -std=c99 -pedantic -Wall -Wextra -c -o def.o def.c
g++ -std=c++11 -pedantic -Wall -Wextra -c -o main.o main.cpp
gcc -std=c99 -pedantic -Wall -Wextra -c -o use.o use.c
g++ -std=c++11 -pedantic -Wall -Wextra -o extern_C_inline def.o main.o use.o
foo 仅在extern_C_inline 中出现一次,因为编译器在不同目标文件中输出的不同版本被合并,但我想知道这种行为是否由标准指定。如果我删除 foo 的 extern 定义并使其成为 static 则 foo 将多次出现在 extern_C_inline 中,因为编译器在每个编译单元中输出它。
【问题讨论】:
-
@BenVoigt:是的,不过语义略有不同。
-
@jxh 在 C 中,您需要在某处使用外部内联定义,以确保目标文件中存在非内联版本。见stackoverflow.com/questions/216510/extern-inline
-
@jxh 如果我将 foo 设为静态,那么它将多次出现在可执行文件中,这将增加可执行文件的大小。
-
@jxh "make it static" 通常不是一个好的解决方案,它会产生其他后果并改变程序的语义(例如,如果
foo()中有一个静态局部变量,则将@987654342 @static 意味着您在每个翻译单元中获得不同的静态局部变量,而不是整个程序的单个局部变量)。在有意义的地方使用static,而不仅仅是解决链接器错误。 -
很有趣,这正是我不喜欢的地方。宏很烂。
标签: c++ c inline-functions