LConst PConst - C++
Tags: cpp, programming, cppsenioreas
Published: 2023-07-22 08:47:32

---
title: LConst PConst - C++
published: true
date: 2023-07-17 09:00:00 UTC
tags: Cpp,programming,CppSenioreas
canonical_url: https://cppsenioreas.wordpress.com/2023/07/17/lconst-pconst/
---

The `const` keyword is widely used within almost every C++ program. It symbolizes the idea of a constant variable, object, function, and more, and is meant to forbid us from manipulating and changing the content of a memory location within a certain scope. However, as we learned before “There is nothing more deceptive than an obvious fact.” (Sherlock Holmes).

## Const Rules

In this article, I won’t dive deeply into the const rules, but just move briefly on `const` ideas I consider as crucial for the point I want to talk about.

Let’s start with the basic rules of `const`. The most basic `const` example is a constant variable:

```cpp

const int a = 42;

```

In this example, we initialize a constant integer with a value of 42. Any const variable should be initialized at the creation stage (due to the inability to initialize it later). Once the variable is initialized, there is no way to change it (Well… `const_cast` but it didn’t get into this article scope).

**Const location**

`const` keyword can be written in multiple locations of the type:

```cpp

const int a = 5;
int const b = 6;

```

The result is the same, in both cases the variables are constant. However, this ability has a great impact when pointers join the picture.

```cpp

int val;
const int* a = &val;

```

In this example, we initialize a mutable (not const) int variable named “val”, and a “const” pointer to it called “a”. Now, I say “const” because it’s only a partial const pointer. here is actually applied only to the pointer’s value, not the pointer itself. which means that we can modify this pointer to point to another variable, but we won’t be able to modify the variable content through this pointer. For example:

```cpp

int val;
const int* a = &val;

// *a = 5; // Won't compile. The integer content is protected by the const qualifier.

int val2;
a = &val2; // Works just fine.

```

Now, this also means that we can create the pointer variable without assigning a value to it at the creation stage:

```cpp

// const val; // doesn't compile
const int* a; // Works.

```

If we want to protect the pointer, we have to change the `const` qualifier location. Let’s inspect the different possible locations for the `const` qualifier in this example:

```cpp

const int* a; // the int content is being protected.
int const* b; // the int content is being protected.

int val;
int* const c = &val; // the pointer is being protected, and therefore have to be initializes at the creation stage.

```

We can combine the different `const` locations as long as they don’t repeat the meaning in the same variable:

```cpp

int val;
const int* const a = &val; // both the pointer and its content are protected.
int const* const b = &val; // both the pointer and its content are protected.
// const int const c; // Won't compile because the secound const qualifier have the same meaning of the first const qualifier.

```

The rule is simple if a `const` is the first qualifier in the type, the `const` will be applied to the next element of it. Otherwise, it’ll always be applied to the previous component of it.

_Side note:_ A constant pointer equivalent is a reference variable, for example:

```cpp

int val;
int &a = val;
int *const b = &val;

```

Variables “a” and “b” here have the same meaning, they are both protecting the pointer from changes.

## Class Const Member Functions

Now that we know the rules for constant variables, let’s talk about constant functions.

Constant functions are defined as functions that can not modify a class’s variables. For example:

```cpp

class A {
public:
    void func() const {
        // a = 5; // Won't compile
    }

private:
    int a;
};

```

Everything seems great, right? Let’s inspect another case:

```cpp

class A {
public:
    void func() const {
        // a = &val; // Won't compile
    }

private:
    int *a;
    int val;
};

```

So far, everything seems just right. If a function is const, the class’s members can not be modified. It’s time to break this rule a little:

```cpp

class A {
public:
    A() : a(&val) {}

    void func() const {
        *a = 42; // Wait, WHAT?!
    }

private:
    int *a;
    int val;
};

```

I guess it’s the right time to go back to the quote “There is nothing more deceptive than an obvious fact.” of Sherlock. The constant function only protects the last element of the class’s members’ types. So in this example, we modified a member variable content through a pointer member inside a constant member function.

Marking this function as a `const` function is a mistake that might lead to bugs if someone will relay on this `const` qualifier. This function actually performs a hidden `const_cast` and it shouldn’t. In order to fix this issue, the right thing would be to remove the `const` qualifier from this function.

Code inspection tools sometimes might advise us to add a `const` qualifier to this function, because the compiler allows that, but we shouldn’t. Adding a `const` qualifier to a class’s function should always be done only after careful consideration of whether this function modifies the class’s state/variables or not.

Let’s see an even more confusing example:

```cpp

class A {
public:
    A() : a(val) {}

    void func() const {
        a = 42; // Oh no...
    }

private:
    int &a;
    int val;
};

```

This time we even don’t see the `*` when modifying the content. And it’s not even a UB! It’s totally legal by the language’s standard.

## Conclusion

The title LConst PConst stands for Logical Const vs. Physical Const. We should always prefer to use the logical one over the physical one, and the compiler doesn’t help us this time.

I didn’t dive into more aspects of the `const` qualifier in this article, but I might do it in future articles. If you have a specific request, feel free to contact me on the dedicated channels of this blog like Discord and Telegram.

Feel free to leave your opinions in the comments section.