Почему я иногда могу изменить объект const, а иногда нет? - PullRequest
0 голосов
/ 23 февраля 2012

У меня есть две части кода, где я пытаюсь изменить значение в месте, доступном только для чтения. Один из них выбрасывает ошибку.

1stcode.c

void main()
{
  int const k=9;
  int *p=&k;
  *p=10;
  printf("%d",k);
}

2ndcode.c

void main()
{
      int  const * p=5;
      printf("%d",++(*p));
}

Здесь 1stcode.c позволяет мне просто изменить область памяти только для чтения, но 2ndcode.c выдает ошибку:

error: increment of read-only location '*p'

Почему так, когда оба места доступны только для чтения?

Ответы [ 3 ]

4 голосов
/ 23 февраля 2012

1-й пример также не будет компилироваться, если вы повысите уровень предупреждения вашего компилятора.


Обратите внимание, что во втором примере вы объявляете указатель на адрес 5, который никогда не будет полезен.

2 голосов
/ 23 февраля 2012

Также неверен первый код.

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

Код по-прежнему компилируется, поскольку C слабо типизирован и допускает неявное преобразованиемежду несовместимыми типами (в данном случае от const int* до int*.

(обратите внимание, что это отличается в C ++, который является более строгим и может привести к ошибке компиляции, если вы попытаетесь выполнить такое преобразование.)

0 голосов
/ 23 февраля 2012

Из онлайн-стандарта C99 :

6.7.3 Классификаторы типа
...
5 Если предпринята попытка изменитьобъект, определенный с помощью const-квалифицированного типа посредством использования lvalue с не-const-квалифицированным типом, поведение не определено.Если предпринята попытка обратиться к объекту, определенному с типом, определенным с помощью volatile, посредством использования lvalue с типом, не определенным с помощью volatile, поведение не определено. 115)

ВыВы пытаетесь изменить содержимое от k (объект, определенный с типом, определенным const) до *p (lvalue с типом, не квалифицированным как const), таким образом, поведение не определено, где "undefined" простоозначает, что стандарт не требует от компилятора каких-либо конкретных действий.В этом случае компилятор перевел код таким образом, что операция «работает», но вы не должны полагаться на повторяемость этого поведения.Более умный компилятор (или более строгий параметр предупреждения) может выдать диагностику и прекратить трансляцию в этот момент.Или это не так.Эту проблему трудно обнаружить в общем случае, поэтому я подозреваю, что поведение просто остается неопределенным.

Во втором случае вы объявили p как указатель на const int;вам не разрешено изменять *p, что ++(*p) пытается сделать.

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