使用const外部值作为非const外部值是否安全?

xyl*_*per 1 c gcc const shared-libraries extern

请参阅下面的代码和结果:

foo.c的:

const int extern_const = 1;
Run Code Online (Sandbox Code Playgroud)

main.c中

#include <stdio.h>

extern int extern_const;

int main(void)
{
    printf("before: %d\n", extern_const);
    extern_const = 2;
    printf("after : %d\n", extern_const);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译和结果:

$ gcc -shared -fpic foo.c -o libfoo.so
$ gcc main.c -L. -lfoo  -o test
$ LD_LIBRARY_PATH=`pwd` ./test
before: 1
after : 2
Run Code Online (Sandbox Code Playgroud)

我声明了一个const int变量extern_const,它驻留在一个共享库中libfoo.so.在main.c中,我声明extern_const只是extern int没有extern const int,并将值从1更改为2. 这是安全有效的吗?

执行结果显示替换仍然有效.我听说覆盖const值会引发未定义的行为,事实上,当我一次编译foo.c和main.c(没有创建共享库)时,程序实际上在第二个printf之前以分段错误结束.

我想知道的是接下来的事情:

  1. 一般来说,更改外部库中任何const变量的值是否安全?
  2. 如果没有,GCC/GNU工具包是否安全?
  3. 如果1.和2.都错了,我是否得到了未定义行为的幸运案例?
  4. 如果1.或2.是正确的,那么有/无库的情况会有什么不同?

Ded*_*tor 5

修改常量对象是Undefined Behavior.什么都可能发生.

在你的情况下,你可能已经变得不幸,因为GCC还没有汇集所有常量变量和文字,它没有把它放入只读部分(定义更多它们可能会发生),而你main()是第一个也是最后一个访问该外部常量对象的代码(虽然在false标志下为非const).

6.7.3类型限定符§6

如果尝试通过使用具有非const限定类型的左值来修改使用const限定类型定义的对象,则行为是未定义的.如果尝试通过使用具有非volatile限定类型的左值来引用使用volatile限定类型定义的对象,则行为是未定义的.