2017-01-02 2 views
2

Мы можем изменить значение константного целочисленного указателя на b, как мы можем убедиться/ограничить случайную модификацию значения?понимание функции (const int * a) указатель на целочисленную константу

#include <stdio.h> 

/** 
* Snippet to under working of "pointer to integer(any) constant" 
* 
* We are able to modify the value of constant integer pointer by b, how 
* can we make sure/restrict accidentally modification of the value . 
* 
*/ 

void modify_value(const int *m, const int *n) { 
    //*m = 50;   // expected error, assignment of read-only location 
    *((int*)n) = 100; // value of pointed by pointer gets updated !! 
} 

int main() { 
    int a=5,b=10; 
    printf("a : %d , b : %d \n", a,b); 
    modify_value(&a,&b); 
    printf("a : %d , b : %d \n", a,b); 
    return 0; 
} 
+4

Не отбрасывайте 'const'? Если вы хотите получить предупреждение об этом, например, в GCC есть «-Wcast-qual». – Ryan

+0

@Ryan, я подумал, как только мы передадим const int *, компилятор не позволит нам изменить указанное значение. Нельзя явно попытаться изменить значение const в производственном коде, интересно, можно ли это полностью предотвратить. – CrazyToExpplore

+0

Я имею в виду, вы можете использовать '-Werror = cast-qual' ...? – Ryan

ответ

3

Насколько я знаю, нет водонепроницаемого способа предотвратить это, но есть способы избежать этого по ошибке.

Например, некоторые компиляторы имеют предупреждения, и вы даже можете сделать предупреждения в ошибке (т. Е. Не скомпилировать, если было вызвано предупреждение). Например, на GCC вы можете использовать -Wcast-qual и -Werror (или -Werror=cast-qual). Но это не будет полностью мешать вам изменять данные, на которые указывает const *, так как со многими предупреждениями есть способы обойти их. Например, вы можете на какой-то платформе с помощью интегрального типа, например (int*)((char const*)m - (char*)NULL), но обратите внимание, что это не переносная конструкция (но я думаю, что вытесняющая константа - это не переносная конструкция).

Если вы хотите пойти немного дальше, вы можете, конечно, перекомпилировать GCC, чтобы лучше отслеживать квалификаторы и запрещать некоторые из этих обходных решений, но это может стоить за отказ от стандартного соответствия.

Другим решением было бы использовать какой-то инструмент для линта. Они часто могут выдавать предупреждения, которые проходят обычные компиляторы. Кроме того, в сценариях сборки вы обычно можете сделать эти предупреждения lint считаться ошибками сборки (а не компилировать файл с предупреждениями о линтах).