2011-12-20 22 views
8

Jestem pewien, że poniższy kod nie powinien się kompilować. Ale w g ++ kompiluje się! Zobacz, jak kompiluje się pod numerem http://codepad.org/MR7Dsvlz.Czy rzutowanie z (wskaźnik na const) na (wskaźnik na nie stały) jest nieprawidłowe C++?

Kod:

#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" 
} 

Czy g ++ w błąd przez kompilację tego?

+0

Jeśli chcesz odrzucić constness (i na pewno jest to dozwolone), to idiomatyczny sposób C++ to zrobić z 'const_cast (ptr1)' - chociaż obsada C też zadziała, jak właśnie widziałeś . –

+1

To jest pomocne, aby przeczytać: http://stackoverflow.com/questions/357600/is-const-cast-safe – Pubby

Odpowiedz

9

Nr Według §5.4.4 w standardzie C++, odlewy, które mogą być wykonywane przez oddanych C-styl to:

— 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 

ten jest powszechnie znany jako „odlewanie z dala const -ness” , a kompilator byłby niezgodny z tą częścią normy, gdyby nie skompilował tego kodu.

Jak zauważyła ildjar, modyfikowanie obiektu const za pomocą odlewania const jest niezdefiniowanym zachowaniem. Ten program nie wykazuje niezdefiniowanego zachowania, ponieważ, mimo że obiekt wskazywany przez wskaźnik do const, sam obiekt nie jest const (dzięki R.Martinho i eharvest za poprawienie mojego złego odczytu).

+0

"Nie" - Więc g ++ powinien skompilować kod? "kompilator byłby niezgodny z tą częścią normy, gdyby nie skompilował tego kodu". - Więc g ++ jest zgodny z tą częścią normy? –

+0

@noshenim Twoje pytanie brzmiało: "Czy g ++ jest błędem, kompilując to?" na które odpowiedziałem "nie". Zatem g ++ powinien, i robi, kompiluje kod i jest zgodny z tą częścią standardu. –

+3

Noshenim, zadałeś sprzeczne pytania. Każda * odpowiedź * na pytanie tytułowe była odpowiedzią * nie * na pytanie o ciało. Bądź ostrożny następnym razem. –

3

Nie. G ++ nie jest błędem poprzez skompilowanie kodu. obsada, którą wykonałeś, jest ważna.

(int *)ptr1 to odlew c. odpowiednik w C++ to const_cast<int*>(ptr1). drugi styl jest bardziej czytelny do odczytania.

, ale potrzeba wykonania tego rzutowania (w celu zmodyfikowania zmiennej stałej) pokazuje problem w projekcie.

1

Linia jest odpowiednikiem *(const_cast<int*>(ptr1)) = 64const_cast to pierwsza obsada, która jest wykonywana podczas korzystania z notacji rzutowania.

Powiązane problemy