1

I understand that implicit conversion from non-const to const is not dangerous when handling values, by example:

int mutable = 5;
const int immutable = mutable;

However, when working with pointers, I can do something as follows:

int some_number = 5;
int *mutable = &some_number;
const int *immutable = mutable;    // <= Legal, but isn't it dangerous?

// Let's try to break const
printf("%d\n", *immutable);        // Prints 5
mutable[0] = 10;
printf("%d\n", *immutable);        // Prints 10

By the way, for double pointers this is not allowed (at least you get a warning)! See this question and the references therein.

Community
  • 1
  • 1
Nibor
  • 1,236
  • 9
  • 23

1 Answers1

5

From the C11 standard (draft N1570):

6.7.3 Type qualifiers

Syntax

  1. type-qualifier:
    const
    restrict
    volatile
    _Atomic

[...]

Semantics:

  1. The properties associated with qualified types are meaningful only for expressions that are lvalues.

[...]

EXAMPLE 1

An object declared

extern const volatile int real_time_clock;

may be modifiable by hardware, but cannot be assigned to, incremented, or decremented.

In simple terms:

const doesn't mean a value never changes. It only means that you are not allowed to change it1.

For callees , const is a restriction, not a promise.
For callers however, it is a promise. Passing a const pointer to a function, you can safely assume that the function will not change your data2, thus is "making a promise to you".


1 ...through the identifier with the const qualifier.
2 ...through the const argument passed to it.

Siguza
  • 21,155
  • 6
  • 52
  • 89
  • I forgot to mention that I use C99, but I guess the standard there is similar. Thanks for the clarification! – Nibor Aug 24 '16 at 13:57
  • But it's strange that for double pointers, a warning is issued indeed, to prevent what I just did above for single pointers, see http://c-faq.com/ansi/constmismatch.html – Nibor Aug 24 '16 at 14:00
  • 3
    "It only means that you are not allowed to change it." - Not even that! I means **the programmer** guarantees not to modify it. – too honest for this site Aug 24 '16 at 14:05
  • @Nibor: C is not `const`-safe across multiple indirections like C++ is. It allows certain constructs which are indeed problematic. But as it is a guarantee by the programmer, it is at your side to not break that contract. – too honest for this site Aug 24 '16 at 14:07
  • 1
    *Passing a const pointer to a function, you can safely assume that the function will not change your data, thus is "making a promise to you"* This is not correct, the function may still change the data via other parameters of global values. – 2501 Aug 24 '16 at 14:12
  • @2501 My example says nothing about such connections though, only about a `const` value being passed to a function, and the function being unable to change the underlying value through that argument. In a way, it is implicitly assuming the absence of such a connection in the same way it is assuming the function not to violate the specification, the hardware to function as expected, and the laws of physics to hold. I was hoping these didn't require explicit declaration. – Siguza Aug 24 '16 at 14:27
  • 1
    That is not what is written in the answer. Your comment adds: *through that argument*, which is an important distinction. – 2501 Aug 24 '16 at 14:29
  • The const may still be legally cast away, so this is really not a guarantee. – 2501 Aug 24 '16 at 14:46
  • @2501: If you cast away `const` and then modify the data pointed at, you get undefined behaviour. You can cast away the const-ness of a character literal all you like, but if your system places them in read-only (`text`) memory, it does you no good if you try to modify the data pointed at. – Jonathan Leffler Aug 24 '16 at 16:19
  • The statement _It only means that you are not allowed to change it_ should be qualified with _via the `const`-qualified pointer_ or something similar. You can change the data pointed at via a pointer that is not `const`-qualified (`mutable` in the question), or via the original (non-`const`) variable name (`some_number` in the question). – Jonathan Leffler Aug 24 '16 at 16:22
  • @JonathanLeffler The function that receives the const pointer doesn't know if the how the object was defined. *If you cast away const and then modify the data pointed at, you get undefined behaviour.* Not exactly. It is only undefined if the object, the const pointer is pointing to, was defined with const. – 2501 Aug 25 '16 at 08:38