how const keyword works in c
In general const
is 100% compiler. When you declare something const, the compiler places restrictions on what it will let you write. It won't let you assign to const scalar, assign through a const reference or or pointer, or invoke a non-const function of const object.
There is no guarantee that the compiler will arrange any sort of runtime protection.
Using const keyword in c
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
.
How do I best use the const keyword in C?
const
is typed, #define
macros are not.
const
is scoped by C block, #define
applies to a file (or more strictly, a compilation unit).
const
is most useful with parameter passing. If you see const
used on a prototype with pointers, you know it is safe to pass your array or struct because the function will not alter it. No const
and it can.
Look at the definition for such as strcpy()
and you will see what I mean. Apply "const-ness" to function prototypes at the outset. Retro-fitting const
is not so much difficult as "a lot of work" (but OK if you get paid by the hour).
Also consider:
const char *s = "Hello World";
char *s = "Hello World";
which is correct, and why?
C++ what is the point of const keyword?
Non-exhaustive list of reasons:
Software Engineering (SWE). SWE is not just programming, but programming with other people and over time.
const
allows to explicitly express an invariant, which lets you and others reason about the code. As the program becomes bigger, these invariants cannot be just memorized. That's why encoding them in the programming language helps.Optimization opportunities.
With the knowledge that certain values will not change, the compiler can make optimizations that would not be possible otherwise. To take this to the max,
constexpr
means that a value will be known at compile time, not just at run-time. This becomes even more important in potentially multi-threading contexts.Example:
What kind of optimization does const offer in C/C++?I leave out whole program analysis which would require a much longer answer and almost certainly is not applicable to generic C++ programs. But whole-program-analysis will allow reasoning of the analyzer or compiler about constness of variables as they get passed between functions, translation units and libraries.
How does the 'const' keyword work?
But how is this actually being implemented?
The language specification leaves this to the discretion of the implementation, as long as the compiler ensures, that the immutability semantics enforces by this are not violated by the program source code (i.e. assignment to a const object gives a compilation error and discarding a const specifier yields implementation defined behavior).
The standard does not require runtime checks. However if an implementation can do/enforce runtime checks, it's perfectly legal to have them.
For example global/static scope const values may be placed in a read-only memory region, like say, ROM in a microcontroller, or pages mapped read-only in an OS with virtual memory. Most executable formats specify a special section for read-only data (like e.g. .rodata
in ELF), which will mapped read-only, and attempting to modify the contents inside that memory region will be caught by the operating system and result in a program exception.
C++ const keyword explanation
void myfunc(const char x);
This means that the parameter x
is a char whose value cannot be changed inside the function. For example:
void myfunc(const char x)
{
char y = x; // OK
x = y; // failure - x is `const`
}
For the last one:
int myfunc() const;
This is illegal unless it's inside a class declaration - const
member functions prevent modification of any class member - const
nonmember functions cannot be used. in this case the definition would be something like:
int myclass::myfunc() const
{
// do stuff that leaves members unchanged
}
If you have specific class members that need to be modifiable in const
member functions, you can declare them mutable
. An example would be a member lock_guard
that makes the class's const
and non-const
member functions threadsafe, but must change during its own internal operation.
C: Behaviour of the `const` keyword
The Java compiler has a small amount of flow logic to allow you to initalise final
variables after their declaration. This is legal Java:
final int something;
if ( today == Friday )
something = 7;
else
something = 42;
Java will detect if any branches leave the final value undefined. It won't analyse the conditions, so this is not legal Java, even though it's logically similar:
final int something;
if ( today == Friday )
something = 7;
if ( today != Friday )
something = 42;
In ANSI C89, const
variables ( other than extern
) must be initialised in the statement they are declared in.
const int something = ( today == Friday ) ? 7 : 42;
The extern
modifier on a declaration tells the compiler that the variable is initialised in a different complation unit ( or elsewhere in this compilation unit ).
In ANSI C99, you can mix declarations and code, so you can declare and initialise a const
variable after a block of assertions and code. Portability of 1999 ANSI C remains an issue.
A work around for C89 is to note that the rules for declarations preceding code work at block scope rather than function scope, so you can do this:
#include<stdio.h>
int main ( void )
{
printf ( "wibble\n" );
{
const int x = 10;
printf ( "x = %d\n", x );
}
return 0;
}
What is the use of the const keyword when assigning structure values?
But what is it's significance here?
None.
When you assign to xx
like xx = something;
you need that something
to have the basic type struct x
. That happens due to the cast. So if you do
(struct x) {0};
an anonymous object of type struct x
will be created and it can be assigned to xx
like:
xx = (struct x) {0};
Now adding a const qualifier in the cast means that the anonymous object is a constant. However, it doesn't really matter that it's constant as you don't write to it anyway. The only operation performed on the anonymous object is the read operation performed during the assignment to xx
. For an assignment it makes no difference whether the source object (RHS object) is a constant or not.
So: No, for your code const
has no significance.
Can we construct code where it matters?
Yes, consider this (obfuscated useless) code:
int y;
y = ++(struct x) {0, 42}.b;
printf("%d\n", y);
It will create an anonymous object with values .a=0
and .b=42
and then increment and return .b
. In other words, it will print 43.
If you add const
to the cast, you'll get a compiler error like:
main.cpp:26:9: error: increment of member 'b' in read-only object
26 | y = ++(const struct x) {0, 42}.b;
| ^~
So here the const
keyword did matter.
Related Topics
Calculate Md5 of a String in C++
Why Is Operator""S Hidden in a Namespace
Std::Lower_Bound Slower for Std::Vector Than Std::Map::Find
How to Analyze Program Running Time
Could We Use Extern "C" in C File Without #Ifdef _Cplusplus
Objects of Different Classes in a Single Vector
Dll Main on Windows VS. _Attribute_((Constructor)) Entry Points on Linux
How to Efficiently Wait for Cts or Dsr of Rs232 in Linux
Get Device Path Based on Usb Vid:Pid in Linux
Function Template Specialization Importance and Necessity
How to Read System Information in C++
Math Interface VS Cmath in C++