考虑以下功能:
void f(int const* p)
{
*const_cast<int*>(id(p)) = 0;
}
假设f
始终以int*
作为参数,这是合法的吗?
我不是在问这是不是一件好事,我只想要一个严格正式的答案。
让我担心的是,如果你能做到这一点,那么优化器在使用consts方面会有更艰难的工作。考虑一个更复杂的例子:
// 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
是否合法?
答案 0 :(得分:6)
如果指向的值实际上是非const,那是合法的,这就是我们首先得到const_cast
的原因。如果值实际上是常量并且你将const
抛弃了,那么它是未定义的。
如果始终为f
提供int*
,那么为什么不宣布f
采用非常量?或者你可以提供过载:
void f(int const* a)
void f(int *a)
这样编译器将调用正确的版本,用户将看到你的意图。调用第一个版本并让它更改值可能会让任何打电话给f
的人感到惊讶。