Consts - Top level, Low level

I'm struggling to understand what can be a Top level const and what can be a Low level const. Can some explain to me in laymen's term's what constitute's either?
I have never heard these terms but my guess is that low level const is data that is protected by the hardware. If the program tries to write to this data it will not work and it might cause the program to crash. High level const could be data that is protected by the programming language. You can still write to this data e.g. by casting away the constness.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>

// these are declarations of the the same function
// top-level cv-qualifiers are discarded
void foo( int, const int* ) ;
void foo( const int, const int* ) ;

void foo( int, const int* ) { std::cout << "foo( int, const int* )\n" ; }
// void foo( const int, const int* ) {} // *** error; redefinition of foo

// these are two different functions
// non-top-level cv-qualifiers are not discarded
void bar( int, const int* ) { std::cout << "bar( int, const int* )\n" ; }
void bar( int, int* ) { std::cout << "bar( int, int* )\n" ; }


int main()
{
   const int c = 78 ; // 'c' is top level const, the object is immutable

   int m = 78 ;
   const int* p = &m ; // pointer to const int
   // this is not top-level constness
   // though 'p' can't used to modify 'm', 'm' itself is not const

   foo( c, p ) ; // fine; top-level cv-qualifiers are discarded .
   foo( m, &m ) ;

   // non-top-level cv-qualifiers are not discarded
  bar( m, p ) ; // bar( int, const int* )
  bar( m, &m ) ; // bar( int, int* )
}


http://liveworkspace.org/code/4aN8lo$0
closed account (zb0S216C)
I think this is what the OP means:

"Top level const": Logical const-ness. Logical const-ness is where the actual bits of some storage, such as an automatic "int", can change state, but remain in a fixed state by some abstract mechanism, like so:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Constant_Integer
  {
    public:
      Constant_Integer( )
          : _M_Data_
        { }

      Constant_Integer( signed int const X_ )
          : _M_Data_( X_ )
        { }

    private:
      signed int _M_Data_;

    public:
      signed int const operator + ( signed int const X_ ) const
        {
          return( _M_Data_ + X_ );
        }
  };

In the above class, "Constant_Integer::_M_Data_" is non-constant, but the class treats it like it is constant. This is logical const-ness, because the actual storage of "Constant_Integer::_M_Data_" can change state, but the class that encapsulates the storage prevents it [the storage] from changing state. In another scenario, logical const is implemented with the "mutable" keyword. Mutable storage is allowed to change state even though it's constant.

"Low-level const": Bitwise const-ness. Bitwise const-ness is where the state of some storage cannot change physically because the hardware prevents such changes, such as ROM. In C++, everything is bitwise constant. Therefore, the following is bitwise constant:

 
int const Value_( 0 );

Here, "Value_" is bitwise constant because the storage itself is declared constant. A smart compiler will place such storage in ROM where the hardware can protect the storage's state.


EDIT: I've just realised that Top-/low-level const-ness is different from bitwise/logical const. Still, there's some info for you :) Sorry.

Wazzak
Last edited on
This is a couple of line's from a book i'm studying:

We use the term top-level const to indicate that a pointer itself is a const.
When a pointer can point to a const object, We refer to that as a low-level const.

And later in the book it has:

... a top-level const is one that applies to the object itself.

I'm a bit confused by the above, Only just learnt to use pointer's and reference's, And the section i'm on now has a lot of const int, const int*, const int & etc...
What book is that? I think that book is the only one that uses this definition.

According to that definition, the following is a "top-level const":

int * const foo;

In terms of parsing the meaning of the constness out of a declaration, it's suggested to read the declaration from right to left. Reading the above declaration from right to left, foo is a "const pointer to an int". Meaning, the int that foo points to can change but foo itself cannot.

The following is a "low-level const":

const int * foo;

Reading the declaration from right to left (sort of), foo is a "pointer to a constant int". Meaning, the int that foo points to cannot change but foo itself can.

Note that the previous declaration can be rewritten as:

int const * foo;

With the above declaration, the "reading the declaration from right to left" makes more sense. Moving the position of const between the '*'s in the declaration will not change its meaning. Moving a 'const' from the right side of a '*' to the left (and vice versa) changes the meaning of the declaration.

e.g.

1
2
const int * const * foo1;
int const * const * foo2;


In the above, the constness semantics of foo1 and foo2 are identical. They are both a "pointer to a constant pointer to a constant int". This means foo1 and foo2 can change but *foo1, **foo1, *foo2, and **foo2 cannot.

1
2
int * const foo1;
const int * foo2;


In the above, the constness semantics are different. foo1 is a "const pointer to an int" while foo2 is a "pointer to a constant int".
Last edited on
I think it should be C++ Primer. The quotes are pretty much lifted word by word from the book. Is there something lacking from that definition shacktar?
I should retract my statement about that book being the only one to use that definition. It's just this was the first time I had seen that definition, i.e. "top/low level" for constness. You can easily learn about constness through tutorials or school and never come across these terms.
Thank's shacktar.

It was from C++ Primer.
1
2
3
4
5
6
7
8
9
10
11
12
int m = 23 ; 

int* const p1 = &m ; // p1 is immutable, p1 is a top-level const
*p1 = 0 ; // the int pointed to can be modified via p1; p1 is not non-top-level const
// p1 = nullptr ; // *** error

// p2 is not top-level const
const int* p2 = &m ; // p2 is a pointer to const int; the int can't be modified via p2
p2 = nullptr ; // p2 itself is non-const; it can be modified
// *p2 = 0 ; // error; p2 is non-top-level const

const int* const p3 = &m ; // p3 is const at both top-level and non-top-level 
Topic archived. No new replies allowed.