要了解严格别名和restrict关键字的用法,我正在尝试下面显示的程序。在这种情况下,两个指针引用相同的内存位置。因此,在没有用户明确说明的情况下,编译器不能进行任何优化(即不使用restrict关键字)。因此,我的理解是,如果没有使用restrict关键字,程序的输出将为40并且限制为'输出将为30(因为' a'在&#34之后不需要从内存中读取; * b + = * a")。但即使有限制,输出也是40.为什么不进行优化?
我正在关注" here"为了理解。
#include <stdio.h>
void merge_two_ints(int * restrict a, int * restrict b) {
*b += *a;
*a += *b;
}
int
main(void)
{
int x = 10;
int *a = &x;
int *b = &x;
merge_two_ints(a, b);
printf("%d\n", x);
return 0;
}
bash-3.2 $ gcc -Wall -O3 -fstrict-aliasing -std = c99 strict_alias2.c
bash-3.2 $ ./a.out 40
答案 0 :(得分:3)
你观察到:
在这种情况下,两个指针引用相同的内存位置。 [...]我的 理解是没有restrict关键字,输出程序 将是40并且限制&#39;输出将是30(因为&#39; a&#39;不需要 在&#34; * b + = * a&#34;)之后从内存中读取。
但是你的期望与C标准直接相反,后者规定:
restrict
限定词[...]的预期用途是宣传 优化, 从所有实例中删除限定符的所有实例 预处理组成符合程序的翻译单元 不改变其含义 (即可观察的行为)。
(C2011 6.7.3/8;重点补充)
此外,6.7.3 / 8也说,
通过限制限定指针访问的对象具有 与该指针的特殊关联。这种关联,定义于 下面的6.7.3.1要求对该对象的所有访问直接或间接使用该特定指针的值。
并且没有详细说明,6.7.3.1明确规定当给定程序不满足其规定时,行为是不确定的。您的程序会触发此规定,并且您预计会产生未定义行为的特定表现形式。 C语言中的任何内容都不能证明这一点。
然而即使有限制, 输出是40.为什么优化没有发生?
C语言永远不会要求一般优化或要执行的任何特定优化。