强制GCC始终加载常量(即只读),即使启用了优化

u3r8eeie  于 2023-11-16  发布在  其他
关注(0)|答案(1)|浏览(132)

假设我有一个const全局变量,因此它是只读的,并将被放置在.rodata节中。我正在使用-O3优化编译代码。这将使编译器(即GCC)在阅读变量时生成不同的代码,这取决于变量本身的值。如果变量被定义为零或一个足够小的值,适合伊萨指令立即字段,它将使用单个指令。如果它很大,它可能会使用几个指令。我希望生成的代码与值无关。我试着将其声明为volatile const,这似乎可以工作,因为它总是生成加载指令来读取值,但是GCC似乎忽略了const字段并将其放置在.data节中。另外,我尝试声明__attribute__((section(".rodata")) volatile。这导致了警告“警告:为.rodata设置不正确的节属性”。
为了避免陷入“XY问题”,我还要说,我的主要目标是让这段代码生成一个尽可能相同的最终二进制文件(即,具有相同大小的相同地址的部分),独立于这些常量变量的值,这些常量变量来自编译时生成的宏。此外,我想这些常量值是在只读数据部分,使他们被标记为RO页表,不能在运行时损坏。
对如何实现我的目标有什么建议吗?

k2arahey

k2arahey1#

除非您启用了链接时优化,否则编译器通常只有在您在同一个.c文件(翻译单元)中定义变量时才能进行这些优化。
因此,您可以在不同的转换单元中定义变量,例如const.c

const int x = 42;

字符串
然后在其他地方使用

extern const int x;


那么,除非你使用链接时优化,否则编译器只需要在其他翻译单元中发出正确的读取,因为它不知道其他情况。
您可以在一个地方使用X宏来完成这些操作,这样您就可以使用

DEFINE_CONST_VAR(int, x, 42);


#include中,每个变量只执行一次。

相关问题