2

Consider the snippet below:

#include <iostream>
int f(int i) {
    return ++i;
}
int i = f(i);

int main() {
    std::cout << i << '\n';
}

Where in the C++ Standard can I find support for the initialization of the global variable i above?

Ayrosa
  • 3,385
  • 1
  • 18
  • 29
  • 2
    What do you mean by support? – Borgleader Feb 17 '15 at 14:42
  • @Borgleader Some statement supporting the call of a function in global scope – Ayrosa Feb 17 '15 at 14:43
  • 2
  • @πάντα ῥεῖ, I ran this code on my compiler and got output as 1. If its supposed to get undefined behavior, then why did I get so...???? – Arun A S Feb 17 '15 at 14:45
  • @Angew Could you be more precise? I didn't find anything in 8.5 about this. – Ayrosa Feb 17 '15 at 14:48
  • People are usually more willing to helpful if you explain what research you did before posting your question. Especially since you are using the language-lawyer tag. – Shafik Yaghmour Feb 17 '15 at 14:49
  • @πάντα ῥεῖ, but when I changed `++i` to `i`, I got output 0. It seems `i` is getting the value 0 by default, I wonder how...??? – Arun A S Feb 17 '15 at 14:50
  • @ShafikYaghmour I searched the Standard for "function call" and apparently didn't find anything that would give support to the declaration above. – Ayrosa Feb 17 '15 at 14:51
  • 1
    @ArunA.S [This question](http://stackoverflow.com/questions/5474349/initialization-of-objects-with-static-storage-duration-in-c-vs-c) seems related to what you are asking – François Moisan Feb 17 '15 at 14:55
  • @Yakk I'm asking the question because I don't think this is UB of course. – Ayrosa Feb 17 '15 at 14:56
  • 9
    @πάνταῥεῖ: It's not UB. `i` has been statically initialised to zero before calling `f(i)` during dynamic initialisation. – Mike Seymour Feb 17 '15 at 14:57
  • Now, one thing I'm not clear on: there are clauses that imply that values lacking an initializer with static or thread scope are zero-initialized. But `i` has an initializer. I am uncertain if "before the initializer runs" we get zero-initialization. Or, on preview, what @MikeSeymour said. – Yakk - Adam Nevraumont Feb 17 '15 at 14:57
  • 3
    @Yakk Yes they are. 3.6.2/2: "Variables with static storage duration (3.7.1) or thread storage duration (3.7.2) shall be zero-initialized (8.5) before any other initialization takes place." – Angew is no longer proud of SO Feb 17 '15 at 14:58
  • @MikeSeymour I see. it makes a difference, if that code appears at global scope or within a function. – πάντα ῥεῖ Feb 17 '15 at 14:58
  • @François Moisan, thanks a lot. I understood the answer on your link much better than the other ones provided. – Arun A S Feb 17 '15 at 14:59
  • @πάνταῥεῖ: Indeed, but this code can't appear in a function since it contains two function definitions. It's a non-local variable, initialised both statically and dynamically as described in [basic.start.init]. – Mike Seymour Feb 17 '15 at 15:00
  • @Ayrosa so, you understand that the tricky part is your use of `i` in the expression to determine `i`, not the call of `f`? Where you intending to ask about calling a function in global scope, or about using the value of a global variable in an expression to determine the initial value of the global variable? – Yakk - Adam Nevraumont Feb 17 '15 at 16:01

1 Answers1

7

Initialisation of non-local variables is described in the chapter titled "Initialization of non-local variables", [basic.start.init]. In C++11, that's 3.6.2.

Initialising using =, the initialiser can be a braced list, or any assignment expression, including a function call, as specified in [dcl.init] (C++11 8.5).

This has static storage duration, so it's first zero-initialised during static initialisation per 3.6.2/2:

Variables with static storage duration [...] shall be zero-initialized before any other initialization takes place.

It is then initialised from its initialiser during dynamic initialisation, since it doesn't meet the criteria for constant initialisation (since the initialiser isn't a constant expression). That passes the statically initialised zero value to the function, which increments it and returns 1. That value of 1 is used to complete the initialisation.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644