2011-01-30 1 views
7

Можно создать дубликат:
Does the evil cast get trumped by the evil compiler?Какова цель определителя констант, если я могу изменить его с помощью указателя в C?

Здравствуйте,

Если я могу изменить константу через указатель, то какова цель этого? Ниже код:

#include <stdio.h> 
#include <stdlib.h> 

int main() 
{ 
const int a = 10; 
int *p = (int *)&a; 

printf("Before: %d \n", a); 
*p = 2; 
/*a = 2; gives error*/ 

printf("After: %d \n", *p); 

return 0; 
} 

ВЫВОД:

До: 10
После: 2
Нажмите любую клавишу для продолжения. , ,

с помощью Visual Studio 2008.

+3

См. [Смеется ли злой бросок со злым компилятором?] (Http://stackoverflow.com/questions/712334/does-the-evil-cast-get-trumped-by-the-evil- компилятор). Это [неопределенное поведение] (http://www.catb.org/jargon/html/N/nasal-demons.html). – ephemient

+0

Теперь скомпилируйте с оптимизацией. – GManNickG

ответ

12

Причина вы можете изменить значение, потому что вы сделали указатель приведение типа, что содранной с const Несс:

int *p = (int *)&a; 

Это const int* приведения типов (а именно &a) до int *, что позволяет вам свободно изменять переменную. Обычно компилятор предупреждал вас об этом, но явный приказ подавил предупреждение.

Главное обоснование позади const - это предотвратить случайное изменение того, что вы обещали не делать. Это не святотатство, как вы видели, и вы можете безнаказанно отбросить const, точно так же, как вы можете делать другие небезопасные вещи, такие как конвертирование указателей в целые числа или наоборот. Идея заключается в том, что вы должны стараться изо всех сил не путаться с const, и компилятор предупредит вас, если вы это сделаете. Конечно, добавление в литье говорит компилятору «Я знаю, что я делаю», и поэтому в вашем случае вышеупомянутое не генерирует никаких предупреждений.

9

Если я могу изменить константу через указателя то, что цель это? ниже код:

Это Неопределенное поведение и следует избегать любой цены:

§ C99 6.7.3p5

Если попытки изменить объекта определяемый с помощью конструкции с напряжением с использованием значения lvalue с неконстанционным, тип не определено.

+1

«следует избегать любой ценой». Но что, если человек сказал, что они причинят мне боль, если я этого не сделаю? :( – GManNickG

+6

@GMan, жертвуя собой, чтобы предотвратить UB, гарантирует место в кодировании Nirvana, где ключевое слово 'static' имеет только одно значение, и дата выпуска Perl 6 известна. – SiegeX

+0

Вы имеете в виду, что они беспокоятся о языках, отличных от Lisp, в кодировании Nirvana ? –