2

We are able to modify the value of constant integer pointer by b, how can we make sure/restrict accidentally modification of the value ?

 #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
    Don’t cast `const` away? If you want a warning about this, there’s `-Wcast-qual` in GCC, for example. – Ry- Jan 02 '17 at 05:48
  • @Ryan, I thought once we pass an const int * , compiler will not allow us to modify the value pointed. one would not explicitly try and change the const value in production code, I wonder if this can be prevented completely. – PartTimeEngineer Jan 02 '17 at 06:02
  • I mean, you can use `-Werror=cast-qual`…? – Ry- Jan 02 '17 at 06:06
  • Thanks @Ryan, yup -Werror=cast-qual helps to catch this error, so is it a good practice to have cast-qual flag always enable ? – PartTimeEngineer Jan 02 '17 at 06:14
  • It’s generally good practice to enable as many warnings as possible with `-Wall -Wextra` and to treat them as errors (if not necessarily with `-Werror`). – Ry- Jan 02 '17 at 06:14
  • 2
    Might as well add `-pedantic` to the compile string and really drill down on your warnings. – David C. Rankin Jan 02 '17 at 06:17
  • @DavidC.Rankin One should note that `-pedantic` is not as pedantic as people may think. It only emits warnings/errors where the standard requires it to. – skyking Jan 02 '17 at 06:22
  • Possible duplicate of [Is it Undefined Behaviour to cast away the constness of a function parameter?](http://stackoverflow.com/questions/9079104/is-it-undefined-behaviour-to-cast-away-the-constness-of-a-function-parameter) – artm Jan 02 '17 at 06:49
  • @artm I don't think it's a duplicate. That question ask whether it's an UB, while this is about avoiding casting away constness (by mistake). The answers to that question doesn't address that problem. – skyking Jan 02 '17 at 07:50
  • 1
    @artm this question is mainly asking about how to avoid the situation, not about whether it is UB – M.M Jan 02 '17 at 08:04
  • @artm thanks for providing the reference of question which touches upon const pointer. I feel this question is mainly focus on how to avoid it. Ryan and Skyking helped with available options to avoid/detect this situation. – PartTimeEngineer Jan 02 '17 at 08:49
  • As many others have said `*((int *) n ) = 100` is not accidental at all. – Iharob Al Asimi Jan 02 '17 at 12:33

1 Answers1

3

As far as I know there's no waterproof way to prevent this, but there are ways to avoid this by mistake.

For example some compilers have warnings and you can even make warnings into error (ie fail to compile if a warning is triggered). For example on GCC you can use -Wcast-qual and -Werror (or -Werror=cast-qual). But this will not completely prevent you from modifying data pointed to by const *, as with many warnings there are ways to work around them. For example you could on some platform cast via an integral type, for example (int*)((char const*)m - (char*)NULL), but note that this is not a portable construct (but I think the casting away constness is a non-portable construct anyway).

If you want to go a bit further you could of course recompile GCC to better keep track on qualifiers and prohibit some of these workarounds, but that might be at the cost of dropping standard conformance.

Another solution would be to use some kind of lint tool. These often can emit warnings that normal compilers pass. Also in your build scripts you can normally make these lint-warnings to be considered build errors (and not compile a file that has lint warnings).

skyking
  • 13,817
  • 1
  • 35
  • 57