通过像这样的const修改nonconst指针是合法的吗?

时间:2014-01-02 11:15:49

标签: c++ c++11

考虑以下功能:

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是否合法?

1 个答案:

答案 0 :(得分:6)

如果指向的值实际上是非const,那是合法的,这就是我们首先得到const_cast的原因。如果值实际上是常量并且你将const抛弃了,那么它是未定义的。

如果始终为f提供int*,那么为什么不宣布f采用非常量?或者你可以提供过载:

void f(int const* a)
void f(int *a)

这样编译器将调用正确的版本,用户将看到你的意图。调用第一个版本并让它更改值可能会让任何打电话给f的人感到惊讶。