12

In C and C++, one can initialize arrays and structs using braces:

int a[] = {2, 3, 5, 7};
entry e = {"answer", 42};

However, in a talk from 2007, Bjarne mentions that this syntax also works for scalars. I tried it:

int i = {7};

And it actually works! What is the rationale behind allowing the initialization of scalars with braces?

Note: I am specifically not talking about C++11 uniform initialization. This is good old C89 and C++98.

TemplateRex
  • 69,038
  • 19
  • 164
  • 304
fredoverflow
  • 256,549
  • 94
  • 388
  • 662
  • 1
    It's just part of the grammar of C++. Allowing all objects to be initialised this way is more consistent and probably simifies the implementation. – Dave Hillier Jan 09 '13 at 09:42
  • which pre C++11 compiler did you try? – TemplateRex Jan 09 '13 at 09:43
  • Similar topic : [Braces around string literal in char array declaration valid?](http://stackoverflow.com/questions/10147264/braces-around-string-literal-in-char-array-declaration-valid-e-g-char-s) – Nawaz Jan 09 '13 at 09:46
  • @rhalbersma Nothing fancy, just current gcc on Linux (yes, gcc, not g++). And also Visual Studio 2012, with does not support uniform initialization yet. So it can't be that. – fredoverflow Jan 09 '13 at 09:49
  • I am pretty much sure You must have but just to confirm, have you compiled with `-pedantic`? Maybe it is just an compiler extension. – Alok Save Jan 09 '13 at 10:00
  • @Alok Just tried `gcc -pedantic`, and it still works. – fredoverflow Jan 09 '13 at 10:11
  • @AlokSave: It IS allowed by C++03. I know this. I don't doubt it. – Nawaz Jan 09 '13 at 10:17

3 Answers3

4

What is the rationale behind allowing the initialization of scalars with braces?

int is POD. So the brace initialization is allowed in case of int (and for all build-in types), as it makes the initialization-syntax consistent with other PODs.

Also, I guess whatever rationale behind C++11 Uniform Initialization Syntax are, are also (partially) applicable to this syntax allowed by C++03. It is just C++03 didn't extend this to include non-pod types such as the standard containers.

I can see one place where this initialization is helpful in C++03.

template<typename T>
void f()
{
    T  obj = { size() } ; //T is POD: built-in type or pod-struct
    //code
}

Now this can be instantiated with struct which begins with a suitable member, as well as any arithmetic type:

struct header
{ 
    size_t size; //it is the first member
    //...
};

f<header>(); //body becomes : header obj = { size(); }; which is fine
f<size_t>(); //body becomes : size_t obj = { size(); }; which is fine

Also note that POD, whether struct or built-in types, can also be initialized uniformly as:

header h = header(); //value-initialized
int    i = int();    //value-initialized

So I believe one reason is consistency!

Nawaz
  • 353,942
  • 115
  • 666
  • 851
4

The rationale is not mentioned, but from a 2005 C++ Standard draft, 8.5 Initializers [dcl.init], clause 14

If T is a scalar type, then a declaration of the form T x = { a }; is equivalent to T x = a;

Note that the C++ 98 Standard only allows brace initializers for copy-initialization T x = { a }, and not for direct initialization T x { a }, for which only T x(a) works.

UPDATE: see also this question

Community
  • 1
  • 1
TemplateRex
  • 69,038
  • 19
  • 164
  • 304
1

C++ probably inherited this from C. In C the main reason is to have a unique initilizer syntax, in particular for a default initializer. In C the default initializer is {0}.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177