Open In App

Const Qualifier in C

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

The qualifier const can be applied to the declaration of any variable to specify that its value will not be changed (which depends upon where const variables are stored, we may change the value of the const variable by using a pointer). The result is implementation-defined if an attempt is made to change a const.

Using the const qualifier in C is a good practice when we want to ensure that some values should remain constant and should not be accidentally modified.

In C programming, the const qualifier can be used in different contexts to provide various behaviors. Here are some different use cases of the const qualifier in C:

1. Constant Variables

const int var = 100;

In this case, const is used to declare a variable var as a constant with an initial value of 100. The value of this variable cannot be modified once it is initialized. See the following example:

C




// C program to demonstrate that constant variables can not
// be modified
#include <stdio.h>
 
int main()
{
    const int var = 100;
 
    // Compilation error: assignment of read-only variable
    // 'var'
    var = 200;
 
    return 0;
}


Output

./Solution.cpp: In function 'int main()':
./Solution.cpp:11:9: error: assignment of read-only variable 'var'
     var = 200;
         ^

2. Pointer to Constant

const int* ptr;

OR

int const *ptr;

We can change the pointer to point to any other integer variable, but cannot change the value of the object (entity) pointed using pointer ptr. The pointer is stored in the read-write area (stack in the present case). The object pointed may be in the read-only or read-write area. Let us see the following examples.

Example 1:

C




// C program to demonstrate that  the pointer to point to
// any other integer variable, but the value of the object
// (entity) pointed can not be changed
 
#include <stdio.h>
int main(void)
{
    int i = 10;
    int j = 20;
    /* ptr is pointer to constant */
    const int* ptr = &i;
 
    printf("ptr: %d\n", *ptr);
    /* error: object pointed cannot be modified
    using the pointer ptr */
    *ptr = 100;
 
    ptr = &j; /* valid */
    printf("ptr: %d\n", *ptr);
 
    return 0;
}


Output

./Solution.c: In function 'main':
./Solution.c:12:10: error: assignment of read-only location '*ptr'
     *ptr = 100;
          ^

Example 2: Program where variable i itself is constant.

C




// C program to demonstrate that  the pointer to point to
// any other integer variable, but the value of the object
// (entity) pointed can not be changed
 
#include <stdio.h>
 
int main(void)
{
    /* i is stored in read only area*/
    int const i = 10;
    int j = 20;
 
    /* pointer to integer constant. Here i
    is of type "const int", and &i is of
    type "const int *".  And p is of type
    "const int", types are matching no issue */
    int const* ptr = &i;
 
    printf("ptr: %d\n", *ptr);
 
    /* error */
    *ptr = 100;
 
    /* valid. We call it up qualification. In
    C/C++, the type of "int *" is allowed to up
    qualify to the type "const int *". The type of
    &j is "int *" and is implicitly up qualified by
    the compiler to "const int *" */
 
    ptr = &j;
    printf("ptr: %d\n", *ptr);
 
    return 0;
}


Output

./Solution.c: In function 'main':
./Solution.c:18:10: error: assignment of read-only location '*ptr'
     *ptr = 100;
          ^

Down qualification is not allowed in C++ and may cause warnings in C. Down qualification refers to the situation where a qualified type is assigned to a non-qualified type.

Example 3: Program to show down qualification.

C




// C program to demonstrate the down qualification
 
#include <stdio.h>
 
int main(void)
{
    int i = 10;
    int const j = 20;
 
    /* ptr is pointing an integer object */
    int* ptr = &i;
 
    printf("*ptr: %d\n", *ptr);
 
    /* The below assignment is invalid in C++, results in
       error In C, the compiler *may* throw a warning, but
       casting is implicitly allowed */
    ptr = &j;
 
    /* In C++, it is called 'down qualification'. The type
       of expression &j is "const int *" and the type of ptr
       is "int *". The assignment "ptr = &j" causes to
       implicitly remove const-ness from the expression &j.
       C++ being more type restrictive, will not allow
       implicit down qualification. However, C++ allows
       implicit up qualification. The reason being, const
       qualified identifiers are bound to be placed in
       read-only memory (but not always). If C++ allows
       above kind of assignment (ptr = &j), we can use 'ptr'
       to modify value of j which is in read-only memory.
       The consequences are implementation dependent, the
       program may fail
       at runtime. So strict type checking helps clean code.
     */
 
    printf("*ptr: %d\n", *ptr);
 
    return 0;
}


Output

main.c: In function ‘main’:
main.c:16:9: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   16 |     ptr = &j;
      |         ^
*ptr: 10
*ptr: 20

3. Constant Pointer to Variable

int* const ptr;

The above declaration is a constant pointer to an integer variable, which means we can change the value of the object pointed by the pointer, but cannot change the pointer to point to another variable.

Example

C




// C program to demonstrate that the value of object pointed
// by pointer can be changed but the pointer can not point
// to another variable
 
#include <stdio.h>
 
int main(void)
{
    int i = 10;
    int j = 20;
    /* constant pointer to integer */
    int* const ptr = &i;
 
    printf("ptr: %d\n", *ptr);
 
    *ptr = 100; /* valid */
    printf("ptr: %d\n", *ptr);
 
    ptr = &j; /* error */
    return 0;
}


Output

./Solution.c: In function 'main':
./Solution.c:15:9: error: assignment of read-only variable 'ptr'
     ptr = &j; /* error */
         ^

4. Constant Pointer to Constant

const int* const ptr;

The above declaration is a constant pointer to a constant variable which means we cannot change the value pointed by the pointer as well as we cannot point the pointer to other variables. Let us see with an example. 

C




// C program to demonstrate that value pointed by the
// pointer can not be changed as well as we cannot point the
// pointer to other variables
 
#include <stdio.h>
 
int main(void)
{
    int i = 10;
    int j = 20;
    /* constant pointer to constant integer */
    const int* const ptr = &i;
 
    printf("ptr: %d\n", *ptr);
 
    ptr = &j; /* error */
    *ptr = 100; /* error */
 
    return 0;
}


Output

./Solution.c: In function 'main':
./Solution.c:12:9: error: assignment of read-only variable 'ptr'
     ptr = &j; /* error */
         ^
./Solution.c:13:10: error: assignment of read-only location '*ptr'
     *ptr = 100; /* error */
          ^

Advantages of const Qualifiers in C

The const qualifier in C has the following advantages:

  • Improved Code Readability: By marking a variable as const, you indicate to other programmers that its value should not be changed, making your code easier to understand and maintain.
  • Enhanced Type Safety: By using const, you can ensure that values are not accidentally modified, reducing the chance of bugs and errors in your code.
  • Improved Optimization: Compilers can optimize const variables more effectively, as they know that their values will not change during program execution. This can result in faster and more efficient code.
  • Better Memory Usage: By declaring variables as const, you can often avoid having to make a copy of their values, which can reduce memory usage and improve performance.
  • Improved Compatibility: By declaring variables as const, you can make your code more compatible with other libraries and APIs that use const variables.
  • Improved Reliability: By using const, you can make your code more reliable, as you can ensure that values are not modified unexpectedly, reducing the risk of bugs and errors in your code.

Summary

Type Declaration Pointer Value Change
(*ptr = 100)
Pointing Value Change
(ptr  = &a)
Pointer to Variable int * ptr Yes Yes
Pointer to Constant const int * ptr
int const * ptr
No Yes
Constant Pointer to Variable int * const ptr Yes No
Constant Pointer to Constant const int * const ptr No No

This article is compiled by “Narendra Kangralkar“.



Last Updated : 07 Aug, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads