强制 C 编译器不内联数组中的条目

Force the C compiler not to inline an entry from an array

我有一个 C 函数指针数组:

int f1 (void) {
    return 1;
}
int f2 (void) {
    return 2;
}
int (*const functions[])(void) = {f1, f2};

在代码的其他地方(使用第三方工具),我在使用函数数组之前破坏了它的内容。 因此,

result = functions[0]();

应该导致不可定义的行为(甚至 运行 程序的中止)。但事实并非如此。结果就好像破坏从来没有发生过一样。

目前,我可以想象这种行为有两个错误来源:

  1. 破坏没有发生
  2. 编译器在编译时内联数组的内容,因此销毁无效。

到目前为止,第 3 方工具从未表现出不破坏它应该破坏的行为。因此,我不得不假设后者。

如何防止编译器内联函数数组的内容?

编译器可能会内联函数,因为您声明了数组 const 而不是 volatile。所以根据抽象执行模型,可以假设数组永远不会改变。

为确保您可以更改数组,您必须删除 const

为确保您的编译器考虑到来自其他地方的更改,您必须添加 volatile.

你的错误场景对我来说没有多大意义,但如果我们忽略它,你可以像这样防止内联:

typedef int func_t (void);

volatile func_t* const[] = {f1, f2};

这意味着编译器不能期望数组的第一项总是f1,从而无法进行优化。 volatile 在调用之前强制读取函数指针地址,这意味着必须有一个地址,这意味着内联是不可能的,因为内联函数没有地址。