I had some problems with initialising a boolean array and found this answer which stated that "elements have an initial value of false (that is 0) if declared at file scope and indeterminate if declared at block scope." This solved the issue causing my problem but now I'm wondering, why is that?
- and where is your minimal reproducible example?OldProgrammer– OldProgrammer2023-05-25 13:54:34 +00:00Commented May 25, 2023 at 13:54
- 3Because that is what the standard defines. And that is valid for all variable types, not only boolean arrays. Non-static local variables are not initialized by default. If you want them to be initialized, you must do it explicitely.Gerhardh– Gerhardh2023-05-25 13:56:09 +00:00Commented May 25, 2023 at 13:56
- 2@OldProgrammer: An MRE is typically needed for a debugging question, not a question about language design.Eric Postpischil– Eric Postpischil2023-05-25 14:10:01 +00:00Commented May 25, 2023 at 14:10
- It's not the scope that matters, it's the storage duration; specifically, whether the object has automatic storage duration or not (although objects at file scope cannot have automatic storage duration).Ian Abbott– Ian Abbott2023-05-25 14:20:16 +00:00Commented May 25, 2023 at 14:20
4 Answers
Because the standard states so.
From the C standard C11 6.7.9/10:
"... If an object that has static or thread storage duration is not initialized explicitly, then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;"
2 Comments
- All variables declared outside of a function or with the storage class-specifier
statichave static storage duration. - If a variable with static storage duration isn't initialized explicitly by the programmer, it is initialized to zero before
main()is called. If you initialize aboolto zero it's the same thing as initializing it tofalse. - Whereas all variables declared inside a function or as function parameters (often called "locals") have automatic storage duration. If these aren't initialized explicitly by the programmer, their values are indeterminate, essentially meaning unpredictable garbage values.
Comments
Variables declared at file scope can be initialized at load time, when the executable image is brought to memory. This has virtually no cost.
But initializing variables at block scope would require a memset or memcpy every time the block is entered, possibly for nothing, and can have a dramatic impact on the cost.
2 Comments
The reason is that objects of 'static' storage duration without an initializer are initialized to zero or the null pointer (as applicable) [applied recursively to: array elements, structure members, the first member of unions].
Arrays declared at file scope have a 'static' storage duration, independent of whether they are declared with the keyword extern, with the keyword static, or without either.
Arrays declared within a function have an 'automatic' storage duration, meaning that they are not initialized and contain garbage values.
As for why this is so, I can only speculate, but the reason is very likely the following:
- initialization of objects with 'static' storage duration needs to be done only once
- initialization of objects with 'automatic' storage duration needs to be done whenever the respective function is entered – hence there is a performance cost.
The relevant part of the standard (C17) is (draft, 6.7.9 ¶10):
If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static or thread storage duration is not initialized explicitly, then:
- if it has pointer type, it is initialized to a null pointer;
- if it has arithmetic type, it is initialized to (positive or unsigned) zero; [...]