Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does C not support initializing const variables using an if-else statement?

Tags:

c

constants

I want to initialize a const variable using an if-else.
For example:

const int foo;
if (bar) {
    foo = 1;
} else {
    foo = 2;
}

In Java, this is legal code (using final instead of const). The reason is that in all possible outcomes, the variable is assigned once and never reassigned. In C, this is not legal code. What is the reason that it can't be legal code in C?

like image 565
jhourback Avatar asked Aug 06 '17 15:08

jhourback


People also ask

Do const variables need to be initialized?

A constant variable must be initialized at its declaration. To declare a constant variable in C++, the keyword const is written before the variable's data type. Constant variables can be declared for any data types, such as int , double , char , or string .

Can const be initialized?

To initialize the const value using constructor, we have to use the initialize list. This initializer list is used to initialize the data member of a class. The list of members, that will be initialized, will be present after the constructor after colon. members will be separated using comma.

Does C have const correctness?

In C, C++, and D, all data types, including those defined by the user, can be declared const , and const-correctness dictates that all variables or objects should be declared as such unless they need to be modified.

Is const used to declare constants?

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.


2 Answers

You can initialize the foo variable conditionally by means of the ternary operator:

const int foo = bar ? 1 : 2;

Note that, if foo is not an automatic variable, then the initializing expression must be abe to be evaluated at compile-time, otherwise it won't compile.

like image 85
ネロク・ゴ Avatar answered Oct 12 '22 03:10

ネロク・ゴ


You can use the ternary operator, but keep in mind that for objects with static or thread-local storage class, the initializer expression needs to be a compile-time constant:

const int bar =  42;
#define BAR 42

#if 0
    const int foo = bar ? 1 : 2; /*ERROR -- bar is not an integer constant */
#else
    const int foo = BAR ? 1 : 2;
#endif

void fn(void)
{
    const int foo = bar ? 1 : 2;
#if 0
    static const int stc_foo = bar ? 1 : 2; /*ERROR*/
#else
    static const int stc_foo = BAR ? 1 : 2;
#endif
}

The reason an if-else statement can't be used for the initialization is because allowing it would require some rather extensive changes to the C grammar, and it would possibly make the C grammar and semantics much more complicated.

Basically, instead of simply having to verify that the declarator is followed by = and an initializer expression and that that initializer expression is a constant, the compiler would have to remember each static/thread-local variable that hasn't been initialized and then look for unconditionally executed compile-time evaluable branches that follow it an assign to it and use them for the initialization.

Furthermore, statements would have to be allowed in file scope (statements are not allowed in file scope in the current C grammar) and verified for constness and memory access limited to writes to translation-unit-local global variables. Alternatively, they could be implicitly turned into global constructors, but that would introduce additional problems such as constructor ordering between compilation units (which would be hard to resolve if the constructor generation were implicit), the need for implementations to support global constructor in the first place, or the blurring of the currently rather straightforward performance characteristics of static variable assignments.

like image 44
PSkocik Avatar answered Oct 12 '22 02:10

PSkocik