考虑以下函数:
这样做合法吗?假设
让我有点担心的是,如果可以这样做,优化器将更难利用常量。考虑一个更复杂的例子:
这样做是否合法?如果不合法,将参数更改为
void f(int const* p)
{
*const_cast<int*>(id(p)) = 0;
}
这样做合法吗?假设
f
总是以int*
作为参数传递?我不是在问这是否是一个好的做法,只是想要一个严格正式的答案。让我有点担心的是,如果可以这样做,优化器将更难利用常量。考虑一个更复杂的例子:
// identity, always returns what it gets
uintptr_t id(uintptr_t p)
{
static unsigned int const ar[5] {0x12345678, 0x87654321, 0x02468ACE, 0xECA86420, 0x88888888};
for (size_t i = 0; i < 5; ++i)
p ^= ar[2*i % 5];
for (size_t i = 0; i < 5; ++i)
p ^= ar[3*i % 5];
return p;
}
void f(int const* p)
{
uintptr_t q = id(reinterpret_cast<uintptr_t>(p));
*reinterpret_cast<int*>(q) = 0;
}
这样做是否合法?如果不合法,将参数更改为
int* p
是否合法?
id
总是返回它所得到的相同数字。(id 代表身份,也不要在意常量,它们可以是任何东西) - user2345215^
的结合性表明代码等价于p ^= ar[0]^ar[2]^ar[4]^ar[1]^ar[3]; /* 第一次循环 */ p ^= ar[0]^ar[3]^ar[1]^ar[4]^ar[2]; /* 第二次循环 */
,即p ^= ar[0]^ar[2]^ar[4]^ar[1]^ar[3]^ar[0]^ar[3]^ar[1]^ar[4]^ar[2];
。^
的交换律意味着后者等价于p ^= ar[0]^ar[0]^ar[1]^ar[1]^ar[2]^ar[2]^ar[3]^ar[3]^ar[4]^ar[4];
,即p ^= 0^0^0^0^0;
。由于对于所有的x
,x ^ 0 = x
,因此p
不会改变。我猜测 OP 是在测试优化器是否能够找出并删除不必要的代码(只留下return p;
语句)。 - Cassio Neri