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,
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.
CodePudding user response:
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
.
CodePudding user response:
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 integerint * const ptr;
- constant pointer to integerconst 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