可以优化那些代码行吗?
int *ptr = (int *)0x1234;
*ptr = 2;
/* no further code in the scope uses ptr */
我能确定对于任何体面的编译器以及任何级别的优化,都会执行此代码吗?
在两个不同的编译器(-S
和gcc
)上使用gcc-arm-none-eabi
标记对其进行测试,这表明此代码未经过优化。但我正在寻找有关此特定代码的特定保证或指南。
解决了(我相信): 来自Wikipedia - Alias analysis
的Jonathan Mee接受的答案...如果不知道p和q是否为别名,那么就不能执行优化并且必须执行整个代码
据我了解,p
可以在此示例中引用到指向ptr
的{{1}},0x1234
实际上可以被视为对任何类型的引用这个地址在该计划上。
答案 0 :(得分:2)
如果您想确保编译器将值2
写入地址0x12345
,您将对volatile
限定符感兴趣。
volatile int *ptr = (int*) 0x12345; // hardware special address
*ptr = 2;
这意味着对*ptr
的每次读取或写入都被编译器视为副作用,无法优化 1 。
注意,制作这样的指针并写入它有implementation-defined behaviour 2 ,你应该参考你的编译器文档。
1)从C ++最新草案(这个问题在其第一个版本中被标记为C ++),下面给出[dcl.type.cv]/6
。
2)感谢用户StoryTeller。
[dcl.type.cv]/6
[注意:volatile是对实现的暗示,以避免涉及对象的激进优化,因为对象的值可能会被实现无法检测到的更改。此外,对于某些实现,volatile可能指示访问对象需要特殊的硬件指令。有关详细语义,请参阅[intro.execution]。一般来说,volatile的语义在C ++中与C语言相同。 - 尾注]
答案 1 :(得分:2)
不,那些不能被优化掉。
int* ptr = (int*)0x12345
建立一个指向0x12345
寻址的字节的指针,你可能在其他地方分配了它?然而,这样一个奇数的地址不是字节对齐的,最好是未经优化的。
*ptr = 2
将2
分配给该地址。显然优化这些线将导致不同的存储状态。因此,它们无法被优化掉。
alias analysis允许优化引用,通过它可以确定“存储位置是否可以以多种方式访问”
- 不同类型的两个变量不能在同一个别名类中,因为它是强类型的内存,无内存引用(即,不能直接更改内存位置的引用)这两种不同类型的变量无法共享的语言同时记忆位置相同。
- 当前堆栈帧的本地分配不能与来自另一个堆栈帧的任何先前分配位于同一别名类中。这是因为新的内存分配必须与所有其他内存分配不相交。
- 通常,每种记录类型的每个记录字段都有自己的别名类,因为键入规则通常只允许相同类型的记录别名。由于某种类型的所有记录都将以相同的格式存储在内存中,因此字段只能与自身进行别名。
- 同样,给定类型的每个数组都有自己的别名类。
醇>
2 是真正的踢球者,因为这不是本地分配到当前堆栈帧,ptr
可以别名为程序中的任何其他int
,因此编译器无法对其进行优化。