Изменил константу в с - PullRequest
       25

Изменил константу в с

0 голосов
/ 09 октября 2010
const int z = 420;

printf("\n%d | %d",z ,*(&(*(&z+1))-1) );
// O/P:420 | 420

printf("\n%u | %u",&z,(&(*(&z+1))-1) );             //address
// O/P:1310548  | 1310548

*((char *)&z+1) = 21;       //I change value for the 1st-Bit
                                    //corrupting constant

 printf("\n%d | %d",z ,*(&(*(&z+1))-1) );
//the complex(not really) expression evaluates to z
// O/P:420| 5540

printf("\n%u | %u",&z ,(&(*(&z+1))-1) );                
//the complex(not really) expression evaluates to &z
// O/P:1310548 | 1310548

Почему это происходит?

кажется, что я успешно изменил константу в C

, изменив, то есть я изменил биты вдиапазон адресов констант

, поскольку «сложное (не совсем) выражение единства / идентичности» меняет значение после искажения.

, но z остается неизменным.Почему?

почему одни и те же адреса имеют разные значения при разыменовании.?

PS: вы можете использовать любое идентификационное выражение

eg.printf("%d",*(int*)((char*)&(*((char*)&z+1))-1));

[править]

ок, позвольте мне повторноФраза это:

z = 420

&z = 1310548

*(&(*(&z+1))-1) = 420

(&(*(&z+1))-1)  = 1310548

Теперь я делаю, чтобы исказить константу

*((char *)&z+1) = 21;

СЕЙЧАС ПОСЛЕ ПОВРЕЖДЕНИЯ:

z = 420     // NO CHANGE EVEN THOUGH I have corrupted

&z = 1310548

*(&(*(&z+1))-1) = z = 5540    // THE CHANGE

(&(*(&z+1))-1)  = &z = 1310548

ПОЧЕМУ?

Ответы [ 3 ]

6 голосов
/ 09 октября 2010

То, что вы имеете с int const, на самом деле не является константой, а const квалифицированным объектом.Поэтому, если вы играете в игры с изменением этого объекта с помощью манипуляций с указателем, это может быть возможно, но обеспечивает неопределенное поведение.

Единственными целочисленными константами в C являются числовые токены, целочисленные символьные константы, такие как 'a' и enum константы,

6 голосов
/ 09 октября 2010

Поздравляем, вы солгали компилятору, и он вас укусил.

Приведения говорят компилятору, что вы намеренно нарушаете правила и подразумеваете, что знаете, что делаете.С рад позволить вам застрелиться в пресловутой ноге, когда вы делаете это.

5 голосов
/ 09 октября 2010

Здесь не так много тайн. Используя приведения, чтобы сообщить компилятору, что то, что вы изменяете, не const квалифицировано, вы вызываете неопределенное поведение:

6.7.3 / 5 «Классификаторы типов» (C99):

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

Некоторые реализации могли бы поместить переменную z в постоянную память, и вы либо не получили бы видимых изменений, либо какое-либо нарушение прав доступа.

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

...