Using const keyword in c
Asked Answered
E

2

6

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.

Edington answered 27/11, 2021 at 8:36 Comment(4)
What did you expect for the second snippet?Eliza
@Eliza i thought i will get an error like before but i didn't get anyEdington
I don't find my 2 cents sufficient for an answer, but I always try to read the declaration backwards: so static char const *const delimit_method_string: delimit_method_string is a const pointer * which points to a const ((unmodifyable) char, which is static. This helps me understand it.Fiske
@DavidTóth yeah that makes sense, Thanks for the trick:)Edington
R
4

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.

Riehl answered 27/11, 2021 at 8:52 Comment(1)
Good explanation! You might add that static, const and char can appear in any order before the * with the same meaning. static const char *p and static char const *p are equivalent, as well as char const static *p, which is quite confusing :)Mm
P
3
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

Peugia answered 27/11, 2021 at 8:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.