-2

I recently took a look at how pointers work with constants in C, and I read that pointers on constants could lead to modify them:

#include <stdio.h>

int main (int argc, char ** argv) {
  const int x = 1;

  int *y;
  y = &x;

  *y += 1;

  printf("x = %d\n", x); // Prints: 2
  printf("y = %d\n", *y); // Prints: 2

  return 0;
}

Here, I define a constant called x and make a pointer from it so I can modify its value. This means x is not really constant. Is there a way to make it really constant?

EDIT : This question is not a duplicate of this one as I am asking here how we can make a real constant, not how to change a constant through a pointer.

ClementNerma
  • 1,079
  • 1
  • 11
  • 16
  • `y = &x;` (without explicit `(int *)`) should be a compile-time error, you should adjust your compiler flags (e.g. `-pedantic-errors` if you use GCC or Clang). – HolyBlackCat Apr 08 '18 at 14:57
  • Check this link, detailing a similiar issue : https://www.geeksforgeeks.org/const-qualifier-in-c/ – Rann Lifshitz Apr 08 '18 at 14:59
  • But after you add the cast (`y = (int*)&x;`) there is nothing you can do. Often constants end up in write-protected memory and cause a segfault if modified, but sometimes not. It aint hard to shoot yourself in the foot. – HolyBlackCat Apr 08 '18 at 14:59
  • The C standard alone does not provide a way to enforce the `const` property. Operating systems often do. In POSIX, you can allocate one or more pages of memory and use `mprotect` to mark them read-only. – Eric Postpischil Apr 08 '18 at 15:34

1 Answers1

4

First off, const does not define constants; it defines read-only variables.

The line

y = &x;

is a type error; your compiler should have complained about that ("assignment discards qualifiers" or something similar).

*y += 1 attempts to modify a read-only object. Not only is this not guaranteed to work, it has undefined behavior (i.e. anything can happen).

In order to make a real constant, you need to use enum:

enum { x = 1 };

Now &x is an error because constants do not live in memory and don't have an address.

Unfortunately this technique only works for integers.

A commonly seen alternative is macros:

#define X 1

This is not a constant at the language level; instead the preprocessor simply replaces any occurrence of X by 1 during compilation.

melpomene
  • 84,125
  • 8
  • 85
  • 148
  • So, there is no way to define any object as a "real" constant? And, for the error you mentioned, my compiler (gcc on Ubuntu) only shows a warning. – ClementNerma Apr 08 '18 at 15:09
  • 3
    @ClementNerma As far as the C standard is concerned, there are only "diagnostics". Whether something is a warning or an error is at the discretion of the compiler. A good first rule of thumb for C is to treat any warning as an error (or tell the compiler to do so: `-Werror`). You also want to enable `-Wall -pedantic -Wextra`. – melpomene Apr 08 '18 at 15:12
  • Ok, thanks for your explanation :) – ClementNerma Apr 08 '18 at 15:14