2010-08-17 5 views
2

Заканчивать этот кодРазве const не является постоянным?

#include<stdio.h> 

int main() 
{ 

const int a=7; 
int *p=&a; 
(*p)++; 
printf("*p=%d\np=%u\na=%d\n&a%u",*p,p,a,&a); 
getch(); 
} 

Выход вы получаете за это

*p=8 
p=1245064 
a=8 
&a1245064 

Как это возможно ?? Мы объявили переменную a постоянной. Разве это не означает, что местоположение, на которое указывает a, никогда не может быть изменено во время выполнения pgm?

+1

Это не должно компилироваться (это не на Visual C++). Какой компилятор вы используете? –

+0

bcc32 компилятор ... – Laz

+1

он дает только предупреждение о том, что преобразование подозрительных указателей – Laz

ответ

5

Это неопределенное поведение - в вашем случае он работает так, как вы описали, но это может привести к сбою программы или вызвать другие проблемы. В вашем случае const не мешает компилятору распределять переменную в изменяемой памяти, поэтому вы технически можете ее модифицировать, получив указатель на эту переменную и работая через указатель.

3

Неопределенное поведение не следует полагаться ;-)

1

ли вы действительно хотите использовать C, если он на самом деле предотвратить, что от работы? Тот факт, что он работает так, очень в духе языка.

+0

Ха-ха! Это действительно подводит итог c не так ли? – Laz

+1

-1 для разглашения. –

+0

Очень верно !!!!!! –

1

Чтение вашего комментария «это только дает предупреждение о подозрительном преобразовании указателя», это должно быть достаточно ясно, чтобы вывести, что вы делаете что-то незаконное.

Вы назначаете переменную int * значение const int *.

Тот факт, что C не имеет каких-либо проверок времени выполнения, чтобы предотвратить изменение этого адреса памяти, не означает, что это разрешено! (и, по сути, проверка системы статического типа говорит вам об этом).

+0

Не что-то незаконное, как что-то сомнительное. Если это было незаконно, компилятор должен вызывать ошибки вместо предупреждений. – goldPseudo

+0

Тот факт, что вы можете нарушить правило (или закон), не делает его менее незаконным. Как правило, предупреждение в компиляторе означает, что вы делаете что-то неправильно, но оно «достаточно разумно», чтобы выяснить способ продолжения и заставить его работать (иногда нежелательным или неожиданным образом). – fortran

1

Если вы не обнаруживаете это автоматически, просто получите себе достойный компилятор. Например, clang дает мне 4 проблемы с кодом:

clang -c -o test-const.o test-const.c 
test-const.c:17:7: warning: initializing 'int const *' discards qualifiers, expected 'int *' [-pedantic] 
int *p=&a; 
    ^~~ 
test-const.c:19:20: warning: conversion specifies type 'unsigned int' but the argument has type 'int *' [-Wformat] 
printf("*p=%d\np=%u\na=%d\n&a%u",*p,p,a,&a); 
        ~^     ~ 
test-const.c:19:32: warning: conversion specifies type 'unsigned int' but the argument has type 'int const *' [-Wformat] 
printf("*p=%d\np=%u\na=%d\n&a%u",*p,p,a,&a); 
           ~^   ~~ 
test-const.c:20:2: warning: implicit declaration of function 'getch' is invalid in C99 [-Wimplicit-function-declaration] 
getch(); 
^ 
4 diagnostics generated. 

Все это серьезные проблемы.

Смежные вопросы