In your first case, the string literal is decaying to a pointer to a const char. Although s1
really should be const char *
, several compiler allow the other form as an extension:
const char* s1 = "hello world" ;
A sting literal is an array of const char
, we can see this from the draft C++ standard section 2.14.5
String literals which says (emphasis mine going forward):
Ordinary string literals and UTF-8 string literals are also referred
to as narrow string literals. A narrow string literal has type “array
of n const char
”, where n is the size of the string as defined below,
and has static storage duration (3.7).
The conversion of an array to pointer is covered in section 4.2
Array-to-pointer conversion which says:
[...] an expression that has type ‘‘array of type’’ is converted to an
expression with type ‘‘pointer to type’’ that points to the initial
element of the array object and is not an lvalue.[...]
Your other cases do not work because a scalar which can be an arithmetic type, enumeration types or a pointer type can only be initialized with a single element inside braces this is covered in the draft C++ standard section 5.17
Assignment and compound assignment operators 8.5.1
List-initialization paragraph 3 which says:
List-initialization of an object or reference of type T is defined as
follows:
and then enumerates the different cases the only that applies to the right hand side for this case is the following bullet:
Otherwise, if the initializer list has a single element of type E and
either T is not a reference type or its referenced type is
reference-related to E, the object or reference is initialized from
that element; if a narrowing conversion (see below) is required to
convert the element to T, the program is ill-formed.
which requires the list to have a single element, otherwise the final bullet applies:
Otherwise, the program is ill-formed.
In your two cases even if you reduced the initializer to one variable, the types are incorrect
h
is a char and 2
is an int
which won't convert to a pointer.
The assignment could be made to work by assigning the results to an array such as the following:
char s1[] = { 'h', 'e', 'l', 'l', 'o',' ', 'w', 'o', 'r', 'l', 'd' } ;
int a[] = { 2, 3, 1, 45, 6 } ;
This would be covered in section 8.5.1
Aggregates which says:
An array of unknown size initialized with a brace-enclosed
initializer-list containing n initializer-clauses, where n shall be
greater than zero, is defined as having n elements (8.3.4). [ Example:
int x[] = { 1, 3, 5 };
declares and initializes x as a one-dimensional array that has three
elements since no size was specified and there are three initializers.
—end example ] An empty initializer list {} shall not be used as the
initializer-clause for an array of unknown bound.104
Note:
It is incorrect to say that a brace-init-list is not defined for pointers, it is perfectly usable for pointers:
int x = 10 ;
int *ip = &x ;
int *a = {nullptr} ;
int *b = {ip} ;
Will look it up.C11 6.5.2.5/5, rules are as I remembered them. – dyp Jul 21 '14 at 20:40