Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否允许C编译器优化对未分配内存的访问?_C - Fatal编程技术网

是否允许C编译器优化对未分配内存的访问?

是否允许C编译器优化对未分配内存的访问?,c,C,考虑下面的代码 int main() { int* p = (int*)0xABCDEFAB; int a; a = *p; /* do something with a */ return 0; } 是否允许编译器优化对p所指内存位置的访问?由于它未分配(因此其内容未定义),并且内存访问不是程序的可观察行为,因此应该允许它,但另一方面,p可能指向内存映射的I/O 从C标准的角度来看,正式答案是什么 注意:如果p被定义为volatile int*,编译器当然不应该优化

考虑下面的代码

int main()
{
  int* p = (int*)0xABCDEFAB;
  int a;

  a = *p;

  /* do something with a */

  return 0;
}
是否允许编译器优化对
p
所指内存位置的访问?由于它未分配(因此其内容未定义),并且内存访问不是程序的可观察行为,因此应该允许它,但另一方面,p可能指向内存映射的I/O

从C标准的角度来看,正式答案是什么

注意:如果p被定义为volatile int*,编译器当然不应该优化访问,但它不是volatile。

来自

整数可以转换为任何指针类型。除了前面指定的[当整数的计算结果为0时] 结果是定义了实现,可能未正确对齐,可能未指向 引用类型的实体,并且可能是陷阱表示形式

基本上,C标准不处理手工编制的地址,只处理从对象获取的地址


如果在您的实现中,
0xabcdef
结果是未对齐的,那么引用它将是未定义的行为1(并且编译器可以忽略加载)

如果对齐了
0xabcdef
,指针
p
可能不会指向地址
0xabcdef
或类型为
int
的对象,引用该对象将是特定于实现的2。
在这种情况下,编译器不能直接忽略加载,但由于总体行为是特定于实现的,最终结果可能微不足道,可以进行优化

例如,假设我们有一个编译器,其中以ab开头的整数都是 映射到体系结构地址
0xffff
和目标体系结构的地址,该地址始终读取0(在任何系统中)。
编译器可以直接优化加载和归零
a

为了防止后一种情况,您需要使用
volatile


简言之,本标准并未完全涵盖您的案例。
然而,有一个注释在读

用于将指针转换为整数或将整数转换为指针的映射函数旨在 与执行环境的寻址结构保持一致

这意味着,虽然标准不提供任何保证,但您可以期望编译器的行为合理。
此外,根据标准,应记录整数指针映射


一, 引用:
如果为指针指定了无效值,则一元*运算符的行为为 未定义

二, 引用附件J“实施特定行为”中的实施特定方面列表:
-将指针转换为整数或将指针转换为整数的结果。
-从一个

整数可以转换为任何指针类型。除了前面指定的[当整数的计算结果为0时] 结果是定义了实现,可能未正确对齐,可能未指向 引用类型的实体,并且可能是陷阱表示形式

基本上,C标准不处理手工编制的地址,只处理从对象获取的地址


如果在您的实现中,
0xabcdef
结果是未对齐的,那么引用它将是未定义的行为1(并且编译器可以忽略加载)

如果对齐了
0xabcdef
,指针
p
可能不会指向地址
0xabcdef
或类型为
int
的对象,引用该对象将是特定于实现的2。
在这种情况下,编译器不能直接忽略加载,但由于总体行为是特定于实现的,最终结果可能微不足道,可以进行优化

例如,假设我们有一个编译器,其中以ab开头的整数都是 映射到体系结构地址
0xffff
和目标体系结构的地址,该地址始终读取0(在任何系统中)。
编译器可以直接优化加载和归零
a

为了防止后一种情况,您需要使用
volatile


简言之,本标准并未完全涵盖您的案例。
然而,有一个注释在读

用于将指针转换为整数或将整数转换为指针的映射函数旨在 与执行环境的寻址结构保持一致

这意味着,虽然标准不提供任何保证,但您可以期望编译器的行为合理。
此外,根据标准,应记录整数指针映射


一, 引用:
如果为指针指定了无效值,则一元*运算符的行为为 未定义

二, 引用附件J“实施特定行为”中的实施特定方面列表:
-将指针转换为整数或将指针转换为整数的结果。

-任何对象中字节的数量、顺序和编码

C标准对程序的行为没有任何要求。编译器根本不知道这个内存没有分配,它可能是用于某些设备通信的内存(例如直接访问视频缓冲区),所以不允许编译器进行优化it@Lashanep不易挥发,这无关紧要吗?如果你的陈述是正确的,那么如何根据标准来证明它是正确的呢?程序的格式不正确。需要显式转换才能在整数和指针之间进行转换。编译器唯一不允许做的事情就是默默地接受它。C标准对程序的行为没有任何要求。编译器根本不知道这个内存没有分配,它可能是用于某些设备通信的内存(例如直接访问视频缓冲区),所以不允许编译器进行优化it@Lashanep不易挥发,这无关紧要吗?如果你的陈述是c