C/C++  

 

 

 

const

const is a keyword that is used together with a variable. It makes the variable a constant value. It means that the variable declaried with const keyword cannot be changed afterwards. Actuaually the statement 'It makes the variable a constant value' would make you confused. When we say 'variable', it implies that it would be changed anytime, but the variable declaired with const keyword cannot be changed. This would be confusing to many people.  

I understand it might be confusing, but just take it as it is. It is the way it is implemented.

Putting it more of programming jargon, 'const' is the keyword which is used to make variables immutable after their declaration. The word "immutable" refers to an object or variable that, once created or initialized, cannot be changed. If an object is immutable, any modification to it would actually create a new object rather than altering the existing one. This is common with certain data types in programming languages where immutability helps to ensure data integrity and predictability of behavior throughout the code.

 

NOTE : What is the difference between const and #define in terms of functionality ?

    const and #define in C/C++ serve similar roles in defining constants but differ fundamentally in their implementation and behavior:

    • const: This keyword defines constants with a specific type and scope, allowing the compiler to enforce type checking. const variables are stored in memory and can have pointers referencing them. They are scoped, meaning they respect block-level scope rules, which allows for better control over where and how they are visible.
    • #define: This is a preprocessor directive that replaces the defined token with a value or expression before compilation. It does not involve type checking and does not allocate storage. Since #define works at the preprocessor level, it lacks scope and can lead to unintended replacements if not managed carefully.

    Essentially, const offers type safety, scope limitations, and memory allocation, while #define offers broader, unscoped text replacement without type safety or memory considerations.

 

Example 01 >

Let's take a look at a simple example showing the implication of 'const' keyword. This example shows how to declare a variable as const, meaning its value cannot be changed after it is initialized. It also illustrates what happens if there is an attempt to modify a const variable, typically leading to a compiler error, thereby enforcing the immutability of the variable.

void main ()

{

    int a = 0;

    int b = 0;

 

    a = b;

    b = a;

}

 

void main ()

{

    int a = 0;

    const int b = 0;  // this means this integer type variable called 'b' should not (will not) changed.

 

    a = b;

    b = a;  // this line gives an error '[Error] assignment of read-only variable 'b'

               // this is because you tried to change a value for a 'const variable'.

 

}

 

Example 02 >

In case of value type variable, behavior of 'const' is pretty straightforward. However, if the const is used with pointer type (e.g, char *) it gets much more complicated. Take a look at following example. This is the famous strcpy function provided by C library.  As you see here, _Dest is defined as 'char *' but _Source is defined as 'const char *'. This mean that the _Dest value would be changed but _Source value will not be changed within the strcpy() function. It make sence if you consider what ctrcpy() does.

  char * __cdecl strcpy(char * __restrict__ _Dest,const char * __restrict__ _Source);

Now let's take following example and see how it works.

#include<stdio.h>

#include <string.h>

 

int main()

{

    char dest1[255];

    const char dest2[255];

    //const char dest2[255] = "Any String Here";

    //const char *dest2 = "Any String Here";

 

    char src1[] = "source 2";

    const char *src2 = "source 1";

 

    strcpy(dest1,src1);

    printf("dest1 = %s\n",dest1);

    

    strcpy(dest1,src2);    

    printf("dest1 = %s\n",dest1);

 

    printf("dest2 = %s\n",dest2);

    

    /// you would see Compiler Warning as shown below.

   

    strcpy(dest2,src1);  // [Warning] passing argument 1 of 'strcpy' discards 'const' qualifier from pointer target type  

    printf("dest2 = %s\n",dest2);

    

    strcpy(dest2,src2);  // [Warning] passing argument 1 of 'strcpy' discards 'const' qualifier from pointer target type  

    printf("dest2 = %s\n",dest2);

 

    return 0;

}

 

Example 03 >

Let's create a function in two different way as shown below and see what happens. This shows how declaring function parameters as const prevents the function from modifying the input arguments. This usage ensures that the original data passed to the function remains unchanged, offering a safeguard against unintended side effects within the function.

// cAry here is defined without 'const'.

void toUpper(char cAry[255],int n)

{

    

    int i = 0;

    for( i = 0; i <n; i++)

    {

        if(cAry[i]=='\0') break;

        cAry[i] = toupper(cAry[i]); // the contents of cAry[] is being changed here.

                                                  // no problem in this case.

        }   

}

 

/// cAry here is defined with 'const'.

void toUpper(const char cAry[255],int n)

{

    

    int i = 0;

    for( i = 0; i <n; i++)

    {

        if(cAry[i]=='\0') break;

        cAry[i] = toupper(cAry[i]); // the contents of cAry[] is being changed here.

                                     // you would see complier error as follows.

                                     // [Error] assignment of read-only location '*(cAry + (sizetype)...

        }   

}