C语言 了解限制关键字



为了理解严格别名和限制关键字的使用,我正在尝试下面显示的程序。在这种情况下,两个指针引用相同的内存位置。因此,如果没有用户明确告诉,编译器无法进行任何优化(即不使用限制关键字)。因此,我的理解是,如果没有限制关键字,程序的输出将为 40,而"限制"输出将为 30(因为在"*b += *a"之后不需要从内存中读取"a")。但是,即使使用限制,输出也是 40。为什么优化没有发生?

我正在遵循"什么是严格的混叠规则?"来理解。

#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("%dn", x);
return 0;
}

bash-3.2$ gcc -Wall -O3 -fstrict-aliasing -std=c99 strict_alias2.c

bash-3.2$ ./a.out 40

你观察到:

在这种情况下,两个指针引用相同的内存位置。 [...] 我的 理解是,在没有限制关键字的情况下,程序的输出 将为 40,"限制"输出将为 30(因为"a"不需要 在"*b += *a"之后从内存中读取)。

但是您的期望直接与 C 标准相反,该标准指定:

restrict限定符的预期用途是促进优化,并从所有限定符中删除所有实例 预处理组成符合程序的翻译单元 不改变其含义(即可观察的行为)。

(C2011 6.7.3/8;着重号另加)

此外,6.7.3/8 还说,

通过限制限定指针访问的对象具有 与该指针的特殊关联。此关联,定义于 下面的 6.7.3.1 要求对该对象的所有访问都直接或间接使用该特定指针的值。

在不赘述细节的情况下,6.7.3.1明确规定,当给定程序不满足其规定时,行为是未定义的。 您的程序会触发此规定,并且您正在预期生成的未定义行为的特定表现形式。 C语言中没有任何内容可以证明这一点。

然而,即使有限制, 输出为 40。为什么优化没有发生?

C 语言从不要求执行一般优化或任何特定优化。

最新更新