Является ли приведение из (указатель на const) к (указатель на неконстантный) недействительным c ++? - PullRequest
8 голосов
/ 20 декабря 2011

Я уверен, что следующий код не должен компилироваться. Но в g ++ он компилируется! Смотрите его компиляцию на http://codepad.org/MR7Dsvlz.

Код:

#include <iostream>

using namespace std;

int main() {
    int x = 32 ;
    // note: if x is, instead, a const int, the code still compiles, 
    // but the output is "32".

    const int * ptr1 = & x ;

    *((int *)ptr1) = 64 ; // questionable cast
    cout << x ;           // result: "64"
}

Ошибка g ++ при компиляции?

Ответы [ 3 ]

9 голосов
/ 20 декабря 2011

Нет. В соответствии с §5.4.4 стандарта C ++, приведения, которые могут быть выполнены приведением в стиле C:

— a const_cast (5.2.11),
— a static_cast (5.2.9),
— a static_cast followed by a const_cast,
— a reinterpret_cast (5.2.10), or
— a reinterpret_cast followed by a const_cast

Это широко известно как "отбрасывание const -ness", и компилятор не будет соответствовать этой части стандарта, если он не скомпилирует этот код.

Как указывает ildjarn, изменение объекта const путем отбрасывания const ness является неопределенным поведением. Эта программа не демонстрирует неопределенного поведения, потому что, хотя объект, на который указывал указатель на const, сам объект не является const (спасибо R.Martinho и eharvest за исправление моего плохого чтения).

3 голосов
/ 20 декабря 2011

Нет.G ++ не ошибается, компилируя ваш код.актерский состав, который вы сделали, действителен.

(int *)ptr1 - актёрский состав.эквивалент в c ++ равен const_cast<int*>(ptr1).Второй стиль более понятен для чтения.

, но необходимость выполнения этого приведения (для изменения переменной const) показывает проблему в дизайне.

1 голос
/ 20 декабря 2011

Строка *((int *)ptr1) = 64 эквивалентна *(const_cast<int*>(ptr1)) = 64 const_cast - это первое приведение, которое выполняется при использовании обозначения приведений.

...