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.
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.
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 ).
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.
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.
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
.
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 integerYour 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With