c++ - 符合标准的编译器应该能够将这些指针比较中的哪一个优化为“始终为假”?
问题描述
为了更好地理解指针别名不变量在优化过程中的表现,我将一些代码插入著名的 Compiler Explorer中,我将在此重复:
#include <cstring>
bool a(int *foo, int *bar) {
(void) *foo, (void) *bar;
return foo == bar;
}
bool b(int *foo, float *bar) {
(void) *foo, (void) *bar;
return foo == reinterpret_cast<int *>(bar);
}
bool c(int *foo, int *bar) {
(void) *foo, (void) *bar;
// It's undefined behavior for memcpyed memory ranges to overlap (i.e. alias)
std::memcpy(foo, bar, sizeof(int));
return foo == bar;
}
bool d(int *__restrict foo, int *__restrict bar) {
(void) *foo, (void) *bar;
return foo == bar;
}
当前版本的 Clang 和 GCC 都没有将这些函数中的任何一个编译为始终返回false
,所以我的问题是,这些函数中的哪一个在仍然符合 C++ 标准的同时可以编译为始终返回false
?我的(非常有限的)理解说b
, c
, 并且d
都应该以这种方式优化,但我不自信(我也认识到这__restrict
不在标准中,但假装它具有它定义的语义编译器)。
更新
我在每个函数的顶部都包含了对两个指针的取消引用(因此它们不能是nullptr
),并使std::memcpy
调用实际上复制了一个int
.
更新 2
添加了一条评论来解释我的意图std::memcpy
。
解决方案
因为a
这是显而易见的。对于b
代码实际上是正确的,编译器无法做出任何假设。考虑这个调用b
:
int x[2]{};
b(x,reinterpret_cast<float*>(x+1));
如果您正在访问两个参数的值,编译器可能会做出以下假设:
bool b(int *foo, float *bar) {
*foo=10; //*foo is an int (or unsigned int)
//and if foo is a member of a union
//*foo is the active member
*bar+0.f; //bar must be a float within its lifetime so it cannot be
//in the same union as *foo
return foo == reinterpret_cast<int *>(bar);//so always false
}
因为c
我同意你的分析,一个非常聪明的编译器可以优化比较。
因为d
,根据 C 标准,restrict
仅暗示访问对象的方式,而不是指针的值,请参阅 N1570 中的§6.7.3
通过限制限定指针访问的对象与该指针具有特殊关联。这种关联,在下面的 6.7.3.1 中定义,要求对该对象的所有访问都直接或间接地使用该特定指针的值。
与访问指向对象的情况一样,b
智能编译器可以做出假设:
bool d(int *__restrict foo, int *__restrict bar) {
*foo=10;
*bar=12;//So foo and bar point to different objects
return foo == bar;//always false
}
推荐阅读
- python-3.x - from pyftpdlib.handlers import FTPHandler, handler = FTPHandler 这个实例化是如何工作的?
- java - 为什么这个 lambda 表达式可以分配给不同的功能接口?
- sql - 分组但不使用 SQL 外连接聚合,不排序
- c++ - 通过 pragma 更改构建输出目录
- build.gradle - Backendless.initapp 崩溃
- arkit - ARSession.run(_: options) 在调用后异步运行是什么意思?
- android - 设置带有数学主题的工具栏
- python - 在 Python 中创建列表列表时出现“NoneType”属性错误
- javascript - 从外部文件获取 Javascript 值
- javascript - Redux.js , Webpack.js , index.html - 我的 redux 渲染函数没有更新 index.html DOM