强制 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]();
应该导致不可定义的行为(甚至 运行 程序的中止)。但事实并非如此。结果就好像破坏从来没有发生过一样。
目前,我可以想象这种行为有两个错误来源:
- 破坏没有发生
- 编译器在编译时内联数组的内容,因此销毁无效。
到目前为止,第 3 方工具从未表现出不破坏它应该破坏的行为。因此,我不得不假设后者。
如何防止编译器内联函数数组的内容?
编译器可能会内联函数,因为您声明了数组 const
而不是 volatile
。所以根据抽象执行模型,可以假设数组永远不会改变。
为确保您可以更改数组,您必须删除 const
。
为确保您的编译器考虑到来自其他地方的更改,您必须添加 volatile
.
你的错误场景对我来说没有多大意义,但如果我们忽略它,你可以像这样防止内联:
typedef int func_t (void);
volatile func_t* const[] = {f1, f2};
这意味着编译器不能期望数组的第一项总是f1
,从而无法进行优化。 volatile
在调用之前强制读取函数指针地址,这意味着必须有一个地址,这意味着内联是不可能的,因为内联函数没有地址。
我有一个 C 函数指针数组:
int f1 (void) {
return 1;
}
int f2 (void) {
return 2;
}
int (*const functions[])(void) = {f1, f2};
在代码的其他地方(使用第三方工具),我在使用函数数组之前破坏了它的内容。 因此,
result = functions[0]();
应该导致不可定义的行为(甚至 运行 程序的中止)。但事实并非如此。结果就好像破坏从来没有发生过一样。
目前,我可以想象这种行为有两个错误来源:
- 破坏没有发生
- 编译器在编译时内联数组的内容,因此销毁无效。
到目前为止,第 3 方工具从未表现出不破坏它应该破坏的行为。因此,我不得不假设后者。
如何防止编译器内联函数数组的内容?
编译器可能会内联函数,因为您声明了数组 const
而不是 volatile
。所以根据抽象执行模型,可以假设数组永远不会改变。
为确保您可以更改数组,您必须删除 const
。
为确保您的编译器考虑到来自其他地方的更改,您必须添加 volatile
.
你的错误场景对我来说没有多大意义,但如果我们忽略它,你可以像这样防止内联:
typedef int func_t (void);
volatile func_t* const[] = {f1, f2};
这意味着编译器不能期望数组的第一项总是f1
,从而无法进行优化。 volatile
在调用之前强制读取函数指针地址,这意味着必须有一个地址,这意味着内联是不可能的,因为内联函数没有地址。