Does "const" just mean read-only or something more?

41,919

Solution 1

By declaring a variable as const you indicate compiler that you have no intentions of modifying that variable. But it does not mean others don't have! It's just to allow some optimization and to be notified by a compile error (note, that it's mostly compile error, while const == ReadOnly would mean runtime errors).

const does not mean read only, because you can write const volatile, that would mean it could change by itself anytime, but I have no intentions to modify it.

EDIT: here is a classical example: consider I'm writing the code that reads current time from a memory-mapped port. Consider that RTC is mapped to memory DWORD 0x1234.

const volatile DWORD* now = (DWORD*)0x1234;

It's const because it's a read-only port, and it's volatile because each time I will read it it will change.

Also note that many architectures effectively make global variables declared as const read-only because it's UB to modify them. In these cases UB will manifest itself as a runtime-error. In other cases it would be a real UB :)

Here is a good reading: http://publications.gbdirect.co.uk/c_book/chapter8/const_and_volatile.html

Solution 2

The compiler won't allow something declared as const to be modified. It is as you say.

It's mostly used in function prototypes to inform the user that a function won't touch this or that when passed pointers. It also works as kind of failsafe for yourself.

Solution 3

A lot of people are telling you that const means you can't modify it. That is patently false. const can trivially be cast away. Note this snippet:

void foo(const int *somevalue)
{
   int *p = (int*) somevalue;
   *p = 256;  // OMG I AM EVIL!!!!11
}

Your compiler will not stop you from doing this. So, what then is the purpose of const? I'd call it more of a suggestion. It reminds you as you look at function prototypes of the contract that your functions expect. Your compiler will yell at you if you carelessly break it. (But not if you intentionally break it, as with the above cast.)

In some cases the standard intentionally breaks const. Note the return values of strstr for example: by definition it will return some offset into the const buffer you provide it... But the returned value is not const. Why? Well, this would break meaningfully using the return value of strstr on a non-const buffer.

Solution 4

Two byte for byte identical (except for the comments) minimal case examples...

First in C, gcc will emit a warning...

/* Function taking a pointer to an array of
 two read only integers.*/
void a( const int (* parray)[2]);

void b(void)
{
   int array[2] = {1,2};
   const int crray[2] = {1,2}; 
/* C reserves the right to stash this in a read-only location.*/

   a( &array); 
/* warning: passing argument 1 of ‘a’ from incompatible pointer type*/
   a( &crray); /* OK!*/
}

Now the same thing in C++... g++ is quite happy with it.

// Function taking a pointer to an array 
// of two integers which it promises not to modify. 
// (Unless we cast away it's constness ;-P)
void a( const int (* parray)[2]);

void b(void)
{
   int array[2] = {1,2};
   const int crray[2] = {1,2};

   a( &array); // C++ has no problem with this.
   a( &crray); // OK!
}
Share:
41,919
Kim Sun-wu
Author by

Kim Sun-wu

Updated on June 25, 2020

Comments

  • Kim Sun-wu
    Kim Sun-wu about 4 years

    What does const really mean? Read-only seems to encapsulate its meaning for me, but, I'm not sure I'm right.

    If read-only and const are different, could someone tell me why?

    What prompted this question was this answer where he states const "just" means read-only in C. I thought that's all const meant, regardless of whether it was C or C++. What does he mean?

    For an answer to the specific differences in const in C vs C++, I've created a new question: How does "const" differ in C and C++? as per R..'s suggestion.

  • Maxpm
    Maxpm over 13 years
    +1 For "failsafe for yourself." If you know you shouldn't be changing something, declare it as a const and avoid potential errors later on.
  • Kim Sun-wu
    Kim Sun-wu over 13 years
    @ruslik: "by itself"? Could you provide an example?
  • Billy ONeal
    Billy ONeal over 13 years
    @Kim: The variable could be mapped to some form of hardware device. Or it could be that Thread A has it const volatile, and it's changed from thread B, or.... any number of things like that.
  • user2584401
    user2584401 over 13 years
    A location in memory that is only ever modified by some piece of hardware outside the CPU. Say you have a sensor mapped to a location in memory and you want to read the value it's reporting.
  • Kim Sun-wu
    Kim Sun-wu over 13 years
    @ruslik, @Billy, @Matt: What would happen in the example ruslik pointed out if the variable was only marked const? The compiler has no idea what's at that location, so it's not going to get optimized away or any such thing, what's the difference between const/const volatile other than making the code more "correct" to the reader? i.e, does it have any implications for the code itself if it was just marked const? const only guarantees that the code itself doesn't modify that location(without an explicit cast), not that any hardware doesn't, right?
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE over 13 years
    This code has undefined behavior if the object you actually passed a pointer to was declared const. The only time it's valid to write through a pointer from which const qualification was removed is if the originally pointed-to object was non-const. The same applies with other qualifiers like volatile.
  • asveikau
    asveikau over 13 years
    @R.. - I was going to write something like this, actually, but thought it might be distracting to describe... A common example is: If you declare something const outright, your compiler may put it in a read-only data section and you could crash writing to it.
  • Sonny Saluja
    Sonny Saluja over 13 years
    Didn't realize you were looking for a very specific answer. The way your question was worded kinda threw me off.
  • Johannes Schaub - litb
    Johannes Schaub - litb over 13 years
    According to my english, "read only" means that you can only read it, but not necessarily that it won't change.
  • josesuero
    josesuero over 13 years
    @Kim: If it was only marked const, then the compiler could assume that the value wouldn't change "by itself". So in some circumstances, the compiler could optimize away accesses. Initially it doesn't know what's at that location, but once it's been read from, it does know, so it doesn't need to do the same read again the next time you read from that location. Normally, the compiler can (and will) assume that two reads, with no writes in between, will yield the same result, and optimize accordingly. volatile tells the compiler not to make this assumption
  • josesuero
    josesuero over 13 years
    This is a bit of an over-generalization. There are cases where the compiler can't be sure if you might have modified it. Continuing rusliks example, say that you read from now, then write to another non-const DWORD*. Now the compiler has to assume that maybe the write you just peformed was to the same address that now points to, so maybe now has changed. But short of such pointer aliasing, the compiler can assume that unless a variable is marked volatile, it'll contain the same value if you read it two times in a row.
  • Yttrill
    Yttrill over 13 years
    there is no such thing as a const object, nor a const type (despite the incorrect description in the Standard). Your code is correct though: but it is not the object which is const, but the reference or pointer to that object. BTW: in the example you mean "data" not "i". And note: ((Foo*)this)->data = 1; modifies data even inside ConstBar :)
  • Admin
    Admin about 10 years
    Jalf is correct: it doesn't necessarily mean that something outside of the CPU is doing the modifying; just something outside of the function / module / program, that the compiler wouldn't normally expect. The point is to warn the compiler not to make assumptions; not to optimise based on assumptions, in particular.
  • M.M
    M.M over 9 years
    This example doesn't actually show what you think it is showing, it is just an oversight in the C language specification. See here for related answer