是否有可能在C中检测到保留标识符的冲突使用?

rku*_*ara 8 c gcc

根据C标准,如果程序定义或声明了保留标识符,则行为未定义.一类保留标识符是在C标准库中定义的具有外部链接的标识符.

例如,具有未定义行为的程序,请考虑以下内容:file1.c定义了一个time使用外部链接命名的变量,该变量与timetime.h中声明的标准库中的函数冲突.

file1.c中:

int time;

int foo( void )
{
    return time;
}
Run Code Online (Sandbox Code Playgroud)

file2.c中:

#include <time.h>
#include <stdio.h>

extern int foo( void );

int main( void )
{
    foo();
    printf( "current time = %ld\n", time( NULL ) );
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译并运行程序时,会发生seg错误,因为timefile2.c中引用的符号链接到timefile1.c中的变量,而不是C库中的函数.

$ gcc -c -o file1.o file1.c
$ gcc -c -o file2.o file2.c
$ gcc -o test file1.o file2.o 
$ ./test
Segmentation fault (core dumped)
Run Code Online (Sandbox Code Playgroud)

我想知道GCC是否有任何方法可以在编译或链接时检测用户代码中冲突的保留标识符的使用情况.这是我的动机:我正在开发一个应用程序,用户可以在其中编写应用程序的C扩展,然后编译并链接到应用程序的其余部分.如果用户的C代码使用上面示例中的保留标识符,则生成的程序可能会以难以预测的方式失败.

想到的一个解决方案是nm在用户的目标文件上运行类似的东西,并将定义的符号与C库中的保留标识符列表进行比较.但是,我希望在GCC找到可以发现问题的东西.有谁知道这是可能的,还是有任何建议?

PSk*_*cik 4

您可以获取一个可以静态链接的 libc 实现,并-Wl,--whole-archive尝试将其添加到您的目标文件中。

主.c

int time=42;
int main(){}
Run Code Online (Sandbox Code Playgroud)

将其与整个 libc 链接:

$ musl-gcc main.c -static -Wl,--whole-archive
Run Code Online (Sandbox Code Playgroud)

如果您收到多重定义错误或符号类型/大小/对齐方式更改警告,则说明您与 libc 发生冲突。

/usr/local/bin/ld: /usr/local/musl/lib/libc.a(time.lo): in function `time':
/home/petr/f/proj/bxdeps/musl/src/time/time.c:5: multiple definition of `time'; /tmp/cc3bL3pP.o:(.data+0x0): first defined here
Run Code Online (Sandbox Code Playgroud)

或者(并且更稳健),您可以预先包含所有 C (所有 posix)标头,并让编译器告诉您与它发生冲突的位置(我会偶尔这样做一次,否则它会在一定程度上降低你的构建时间。(尽管即使包含所有 POSIX 通常也不如包含单个 C++ 标头那么糟糕))。