-2

I wrote this code:

#include <cstdlib> 
#include <iostream>
#include <stdio.h>

constexpr int foo(int a, int b)
{
    return a*b;
}

int bar(int a, int b)
{
    return a*b;
}

int a = bar(1,2); // Dynamic initialization. This brace-or-equal initializer 
                  // contains expression which is not a constant expression
int main()
{ 
    a = foo(3,4); // Constexpr function invocation. Static initialization.
    std::cout << a; // 12
}

This program outputs 12. I expected that 2 will be outputted. Because every Static Initialization is performed before Dynamic Initialization. I'm confused.

Wolf
  • 8,482
  • 7
  • 48
  • 92
St.Antario
  • 23,179
  • 26
  • 96
  • 243

2 Answers2

3

Assignment is not initialisation. The assignment from foo(3,4) happens after main begins (which is after the initialisation from bar(1,2)), and before printing the value.

Mike Seymour
  • 235,407
  • 25
  • 414
  • 617
  • Is it possible to initialize a variable twice at all? – St.Antario Jun 30 '14 at 15:51
  • @St.Antario: No. Objects are only initialised once. – Mike Seymour Jun 30 '14 at 15:53
  • Is initialization the same concept as definition? – St.Antario Jun 30 '14 at 15:54
  • @St.Antario: They're related, but separate, concepts. The definition of a variable allocates storage for it. Initialisation creates a valid object within that storage. (A dynamic object, created by `new`, is initialised by the new-expression, but doesn't have a definition. A local static variable has a definition, but might never be initialised if the program never reaches the definition.) – Mike Seymour Jun 30 '14 at 16:01
  • @St.Antario It's possible, but you're not likely to do it accidentally, and in most cases, it would be an error if you did. Still, `new (&a) int( 42 );` would do it (although you could only see the difference with class types). – James Kanze Jun 30 '14 at 16:51
  • Mike: Normally, allocation and initialization are bound, both in variable definition and in a `new` expression. You can separate them, however, by allocating with the `operator new` function (or `malloc`, or by defining a `char[]`), and then using placement `new`. – James Kanze Jun 30 '14 at 16:53
2

a is not declared constexpr so it cannot be initialized via a constexpr expression. In the scenario you present, the second "initialization" is in fact a dynamic assignment.

  • Can you provide a quote from Standard which describes what you write. – St.Antario Jun 30 '14 at 15:53
  • The first sentence is wrong: anything can be initialised by a constant expression. `a` not being `constexpr` (or just `const`) means that its value can't be used in a constant expression. – Mike Seymour Jun 30 '14 at 16:03