Is There Const in C

Is there const in C?

There are no syntactic differences between C and C++ with regard to const keyword, besides a rather obscure one: in C (since C99) you can declare function parameters as

void foo(int a[const]);

which is equivalent to

void foo(int *const a);

declaration. C++ does not support such syntax.

Semantic differences exist as well. As @Ben Voigt already noted, in C const declarations do not produce constant expressions, i.e. in C you can't use a const int object in a case label, as a bit-field width or as array size in a non-VLA array declaration (all this is possible in C++). Also, const objects have external linkage by default in C (internal linkage in C++).

There's at least one more semantic difference, which Ben did not mention. Const-correctness rules of C++ language support the following standard conversion

int **pp = 0;
const int *const *cpp = pp; // OK in C++

int ***ppp = 0;
int *const *const *cppp = ppp; // OK in C++

These initializations are illegal in C.

int **pp = 0;
const int *const *cpp = pp; /* ERROR in C */

int ***ppp = 0;
int *const *const *cppp = ppp; /* ERROR in C */

Generally, when dealing with multi-level pointers, C++ says that you can add const-qualification at any depth of indirection, as long as you also add const-qualification all the way to the top level.

In C you can only add const-qualification to the type pointed by the top-level pointer, but no deeper.

int **pp = 0;
int *const *cpp = pp; /* OK in C */

int ***ppp = 0;
int **const *cppp = ppp; /* OK in C */

Another manifestation of the same underlying general principle is the way const-correctness rules work with arrays in C and C++. In C++ you can do

int a[10];
const int (*p)[10] = &a; // OK in C++

Trying to do the same in C will result in an error

int a[10];
const int (*p)[10] = &a; /* ERROR in C */

Is there a const function in C?

Not in standard C, since there are no classes or objects (as in "class instances, i.e. collections of data with associated functions"), there's nothing for the function to be const "against".

There could in theory be such a notation to mean "this function has no globally visible side-effects, it's a pure function of its input arguments" but there isn't.

The GNU GCC compiler supports, as an extension, declaring a function as either const or pure:

int square(int) __attribute__((pure));

The __attribute((pure)) part is GCC-specific.

Const correctness in C vs C++

In addition to the differences you cite, and the library differences that
Steve Jessop mentions,

char* p1;
char const* const* p2 = &p1;

is legal in C++, but not in C. Historically, this is because C
originally allowed:

char* p1;
char const** p2 = &p1;

Shortly before the standard was adopted, someone realized that this
punched a hole in const safety (since *p2 can now be assigned a
char const*, which results in p1 being assigned a char const*); with
no real time to analyse the problem in depth, the C committee banned any
additional const other than top level const. (I.e. &p1 can be
assigned to a char ** or a char **const, but not to a char const**
nor a char const* const*.) The C++ committee did the further
analysis, realized that the problem was only present when a const
level was followed by a non-const level, and worked out the necessary
wording. (See §4.4/4 in the standard.)

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.

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?

Why do most C developers use define instead of const?

There is a very solid reason for this: const in C does not mean something is constant. It just means a variable is read-only.

In places where the compiler requires a true constant (such as for array sizes for non-VLA arrays), using a const variable, such as fieldWidth is just not possible.

Does a const in C always occupy storage?

First, it's been a long time (and many languages ago) since I wrote that so I'm relying on memory here.

It seems unlikely that a const only visible within a file would always need to allocate storage, so I suspect I was referring to a global const defined in one file and readable in other files. In that case there would have to be an address for the linker, and no compile-time optimizer could recognize if that address was never used (I'm not sure here about the capabilities of linkers; whether a linker could detect the lack of reference to that storage and change the code so it doesn't allocate it. Maybe, but it seems a stretch). And if it's global it does seem like it could be in a library where it could be referenced by some as-yet unwritten piece of code, and that would argue for required storage.

Ultimately, however, rely on the standard and not my writing or reasoning. Before drawing a final conclusion I would recommend seeing what the C++ standard says about this (and I only worked on the original one so I'm sure it's changed) vs what the C standard says. C++ might have additional constraints that aren't in the C standard.

Hope that helps.

-- Bruce

How to check if a variable is of const qualifier type in C?

You can use Generic selection (since C11):

#include <stdio.h> 

#define __is_constant_int(X) _Generic((&X), \
const int *: "a const int", \
int *: "a non-const int")

int main(void)
{
const int i = 1;
printf("Variable i is %s\n", __is_constant_int(i));
return 0;
}

Defining constant in c with const keyword

Using the const type qualifier doesn't make something a constant. A constant in C has its own definition.

See § 6.7.3 ¶ 6 of the C11 standard for a description of the const keyword:

If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined. If an attempt is made to refer to an object defined with a volatile-qualified type through use of an lvalue with non-volatile-qualified type, the behavior is undefined.

What you need there is a constant expression; see § 6.6 of C11 for details.

If what you're really wondering isn't "WTF is up with the const qualifier?" but rather what the right solution for your code is, the answer is likely to simply not specify the size of the array:

float user_array[] = {5.1, 7.2, 5.1, 8.45, 23.0, 67.123, 5.1};

This is generally considered good practice as it actually makes your code a bit more robust.



Related Topics



Leave a reply



Submit