Постоянное изменение значения - PullRequest
0 голосов
/ 09 октября 2018

Предположим, у меня есть определение структуры:

struct thing
{
    thing* x;
    int z;

    thing() : x(this), z(0) {}
    void foo() const
    {
        this->x->z++;
    }
};

Обратите внимание, что я создаю изменяемый указатель на себя (злой смех)

И затем я могу использовать это позже, например:

int main()
{
    const thing c;
    c.foo();
    assert(c.z == 1);
    c.foo();
    assert(c.z == 2);
    return c.z;
}

И, как вы можете видеть, кажется, что я могу изменить постоянное значение ...... это UB?

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

[dcl.type.cv] p4:

За исключением того, что любой член класса, объявленный mutable ([dcl.stc]), может быть изменен, любая попытка изменить ([expr.ass], [expr.post.incr], [expr.pre.incr]) константный объект ([basic.type.qualifier]) в течение его времени жизни ([basic.life]) приводит к неопределенному поведению.

[basic.type.qualifier] p1:

A const object является объектом типа const T или неизменяемым подобъектом такого объекта.

c.z является константным объектом, потому что это неизменяемый подобъект c.Ваш код пытается изменить его в течение своей жизни.Следовательно, код имеет неопределенное поведение.

0 голосов
/ 09 октября 2018

Сама функция foo будет в порядке, так как const функции-члены, такие как T::foo() const, просто указывают, что this имеет тип const *T;Тот факт, что (неконстантный) член указывает на один и тот же объект, не имеет значения.

Объект c на первом месте, однако, объявляется как const.Так что UB может изменять содержимое c с помощью любого кода, включая (по сути, правильную) функцию-член foo.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...