Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using const keyword in c

I have been looking at a source code, and i came across this code

    static char const *const delimit_method_string[] =
    {
        "none", "prepend", "separate", NULL
    };

I thought I knew the meaning of const keyword in the C language but after seeing this syntax I am confused as I can't decode the meaning of the syntax, so I wanted to know the meaning of using const like this I searched internet I saw some questions like this in stackoverflow that are,

  1. Meaning of two const in C/C++ signature
  2. Double const declaration

But still I don't understand what's the meaning of the syntax in that code snippet, may be that because I am not good enough with fundamentals of C but I really like to improve it.

So I wrote some code to know how that syntax works, this is what I tried:

    #include <stdio.h>
    
    int main()
    {
        char a = 'A';
        char b = 'B';
        char const * const ptr = &a;

        ptr = &b;

        printf("a is %c\n", *ptr);
        printf("a is %c", a);
    
        return 0;
    }

I got this output, that somewhat I expected.

$ gcc test.c
test.c: In function 'main':
test.c:9:13: error: assignment of read-only variable 'ptr'
    9 |         ptr = &b;
      |  

                    ^

I changed the code and tested again,

    #include <stdio.h>
    
    int main()
    {
        char a = 'A';
        char b = 'B';
        char const const *ptr = &a;
    
        ptr = &b;

        printf("a is %c\n", *ptr);
        printf("a is %c", a);
    
        return 0;
    }

this time the output is not what I expected,

$ ./a.exe
a is B
a is A

I really appreciate if someone can explain what is the correct way of using const in C and also how the syntax in first code snippet works.

like image 286
ABHIJITH EA Avatar asked Nov 27 '21 08:11

ABHIJITH EA


People also ask

Why should I use const in C?

These uses of const just indicate that you will not change the variable; they don't change how or where the variable is stored. The compiler can of course work out that a variable is not changed, but by adding const you allow it to enforce that.

Is const allowed in C?

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 const variable by using pointer ).

Is const better than #define in C?

In general, const is a better option if we have a choice and it can successfully apply to the code. There are situations when #define cannot be replaced by const. For example, #define can take parameters (See this for example). #define can also be used to replace some text in a program with another text.

How do you declare constants in C?

The const keyword Variables can be declared as constants by using the “const” keyword before the datatype of the variable. The constant variables can be initialized once only. The default value of constant variables are zero.


2 Answers

This declaration

static char const *const delimit_method_string[] =
{
  "none", "prepend", "separate", NULL
};

declares an array with the name delimit_method_string of pointers to string literals.

In C opposite to C++ string literals have types of non-constant character arrays. Nevertheless you may not change a string literal. Any attempt to change a string literal results in undefined behavior. So it is better to declare pointers to string literals the following way as for example

const char *s = "Hello";

So you could declare the above array like

static char const * delimit_method_string[] =
{
  "none", "prepend", "separate", NULL
};

But the programmer who declared this array also wanted to declare at as a constant array. That is he wanted that its elements can not be changed.

For the declaration above you can write for example

delimit_method_string[0] = "all";

To prevent such a changing elements of the array must be constant. To do this you need to write

static char const * const delimit_method_string[] =
{
  "none", "prepend", "separate", NULL
};

Now the elements of the array that have the pointer type const char * are constant due to the second qualifier const.

Tom make it more clear consider the following declarations.

char *p;

This declaration declares a non-constant pointer to a non-constant object of the type char.

const char *p;

This declaration declares a non-constant pointer to a constant object of the type char.

const char * const p;

This declaration declares a constant pointer to a constant object of the type char.

The last declaration may be rewritten like

const char ( * const p );

As for this your declaraion

char const const *ptr = &a;

then on of the two qualifiers const is redundant because the both refer to the type specifier char.

like image 79
Vlad from Moscow Avatar answered Oct 03 '22 15:10

Vlad from Moscow


char const const *ptr = &a;

This double const does not have any special meaning as both are on the same side of the *. Additional const qualifiers are ignored by the compiler. You can write char const const const const const*ptr = &a; It is the same as char const *ptr = &a; which means:

pointer to constant character

If we change it to

char const * const ptr = &a;

It will mean:

constant pointer to constant char

Your snippet will stop to compile: https://godbolt.org/z/sM9qnv8fq

examples:

  • const int *ptr; - pointer to constant integer
  • int * const ptr; - constant pointer to integer
  • const int * const ptr; - constant pointer to constant integer

Your first example static char const *const delimit_method_string[] declares:

static array of constant pointers to constant character

BTW I personally prefer to have the first const before the type ie:

static const volatile char *const delimit_method_string[]

const char *p

like image 37
0___________ Avatar answered Oct 03 '22 15:10

0___________