Вопрос по c – как избежать изменения значения const в C

1

Привет, я новичок в мире программирования, Я хочу знать, как избежать изменения значения константной переменной.

<code>#include <stdio.h>
int main()
{
 const int i = 10;
 int * p = &i;
 *p = 20;
 printf("*p = %d\ni = %d\n", *p,i);
 printf("%u\n%u\n",&i, p);
 return 0;
}
</code>

здесь, в вышеприведенной программе, я получаю только предупреждение, но без ошибки, когда я присваиваю значение константному полю через указатель, но когда я печатаю, out не отличается:

<code>*p = 20
i = 10
3210723532
3210723532
</code>

Итак, какая польза от получения указателя на const, когда он не может быть изменен.

@majie: попробуйте с оптимизацией. caf
@JensGustedt: некоторые предупрежденияnot Требуется языком, хотя, и просто раздражение (например, & quot;Suggest parantheses around assignment used as truth value& Quot;). caf
GCC v4.5.2 на Linux дает мне вывод*p = 20 i = 20Странно, что ваш вывод отличается. majie
Просто никогда не игнорируйте предупреждение. Язык C только указывает, что «диагностика» должен быть выдан. Предупреждения так же серьезны, как и ошибки. Jens Gustedt
Какой компилятор вы используете? Fred Foo

Ваш Ответ

4   ответа
0

#define вместо.

Объекты объявленыconst не являются постоянными в английском значении этого термина, они «только для чтения».

#include <stdio.h>
int main()
{
 #define I 10
 int * p = &I; // illegal &I
 *p = 20;
 printf("*p = %d\nI = %d\n", *p,I);
 printf("%u\n%u\n",&I, p); // illegal &I
 return 0;
}
Error: User Rate Limit Exceeded#defineError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded#undef IError: User Rate Limit Exceeded#define I 13Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededIError: User Rate Limit Exceeded<complex.h>.
1

предупреждениями и ошибками.

Преобразованиеconst int * вint * без приведения это нарушение ограничения, которое требует диагностики.

Это относит его к той же категории, что и синтаксическая ошибка: ваш код не является допустимой программой ISO C, и поведение не определено, если он все равно транслируется и выполняется.

К сожалению, многие компиляторы не различают требуемую диагностику от добавляемой дополнительной диагностики, и, что еще хуже, они иногда требуют диагностики в качестве предупреждений. Это разрешено: стандарт С не предусматривает, что программы, которые требуют диагностики, должны быть защищены от перевода и выполнения. Посылая предупреждение, компилятор удовлетворяет требованию диагностики, и это все.

Другая проблема заключается в том, что многие компиляторы C даже не принимают стандартный диалект ISO C, если их об этом не просят, а вместо этого принимают свой собственный диалект, который может иметь несоответствующие (т.е. не обратно совместимые) расширения.

Компилятор GNU C понимает диалект C, называемый GNU C 89, если вы не предоставляете ему никаких вариантов диалекта.

Таким образом, по иронии судьбы, на этом диалекте, это просто предупреждение для преобразованияconst int * вint * без приведения, тогда как некоторые легальные программы C90 полностью отклонены.

Таким образом, в основном вы всегда должны понимать, как управлять входным диалектом вашего компилятора, и следить за всеми предупреждениями, которые вы должны понять сами, являются ли они реальными нарушениями языка или просто прихотями компилятора писатели («предложить скобки вокруг этого выражения»).

Это неплохая идея для компиляцииgcc -Wall -W -ansi (если вы программируете на C90; или-std=c99 вместоansi для C99) и убедитесь, что нет предупреждений. Даже стилистические, которые предлагают дополнительные скобки и тому подобное. Если вы недостаточно дисциплинированы, чтобы следить за предупреждениями, добавьте-Werror превратить их в ошибки, которые не в состоянии вашей сборки. Некоторые также рекомендуют-pedantic.

Если вы будете следовать этой дисциплине, подрывconst int не будет проникать в вашу кодовую базу.

2

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

Вы должны относиться к предупреждениям компилятора очень серьезно. Если ваш код компилируется без предупрежденийor ошибки, тогда это, вероятно, законно (что не означает, что это действительно будет работать!).

@ user954299: если вы не хотите менятьconst объект, тогда просто не меняйте его. Компилятор предупредил вас об этом. Измените свой код, чтобы вы не получали никаких предупреждений, и вы (вероятно) не будете менять какие-либоconsts. Если вы изменитеint *p = &i; вconst int *p = &i;вы будете избегать предупреждения в этой строке и получите новую диагностику*p = 20;, Итог: воспринимайте предупреждения очень серьезно.
Есть ли способ, чтобы я хотел избежать использования указателя для изменения значения константной переменной. user954299
@avakar: Это не может быть практичным. Но gcc, хотя и выдает предупреждения для многих недопустимых конструкций, имеет-Werror опция, которая превращает предупреждения в фатальные ошибки.
Хотя вы технически исправлены, вместо этого OP должен получить лучший компилятор.
+1, он также выдает предупреждения для многих допустимых конструкций;)
7

компилятор выдаст предупреждение из-за кодаint * p = &i;

и значение i не изменяется, потому что компиляция оптимизирует код, я использую gcc для проверки кода:

если я используюgcc -O0 const.c -o const , O0 не представляет оптимизацию компилятора, результат

*p = 20
i = 20
1114013412
1114013412

но когда я используюgcc -O2 const.c -o const, O2представляет оптимизацию компилятора, результат

*p = 20
i = 10
1262279764
1262279764

Итак, компилятор знает, что типi являетсяconst и заменяетi от10 во время самой компиляции, и, следовательно, код становится

 printf("*p = %d\ni = %d\n", *p,10);

Также вы можете использоватьgcc -S const.c заглянуть в код сборки.

Error: User Rate Limit Exceeded

Похожие вопросы