Is
char x[10] = "banana";
considered to be a implicit conversion from const char[7]
to char[10]
?
Since std::is_convertible<const char[7], char[10]>::value
evaluates to false
the obvious answer would be that it isn't, but I couldn't find a proper definition of implicit conversion anywhere. Reading cppreference I'd say that it is because:
Implicit conversions are performed whenever an expression of some type T1 is used in context that does not accept that type, but accepts some other type T2; in particular: ... when initializing a new object of type T2, including return statement in a function returning T2;
although I'm not sure why they didn't exclude explicit constructors from this case.
Follow-up question (which may be useless):
Are arrays completely excluded from any kind of conversions (meaning array-to-array conversions) ?
CodePudding user response:
In this declaration
char x[10] = "banana";
there is no conversion. Elements of the string literal are used to initialize elements of the array. In fact it is equivalent to
char x[10] = { 'b', 'a', 'n', 'a', 'n', 'a', '\0' };
If instead of the array you declared a pointer like
const char *x = "banana";
then the string literal having the type const char[7]
would be implicitly converted to a pointer to its first element of the type const char *
.
The above declaration is equivalent to
const char *x = &"banana"[0];
CodePudding user response:
Language-lawyerly speaking, initializing char array from string literal is a implicit conversion.
An expression
E
can be implicitly converted to a typeT
if and only if the declarationT t=E;
is well-formed, for some invented temporary variablet
([dcl.init]).
Note that the core language only defines implicit conversion from an expression to a type. So the meaning of "implicit conversion from const char[7]
to char[10]
" is undefined.
is_convertible<From, To>::value
is false
whenever To
is an array type, because it is defined to produce false
if To
is not a valid return type, which an array is not. (This can be implemented in different ways.)
The predicate condition for a template specialization
is_convertible<From, To>
shall be satisfied if and only if the return expression in the following code would be well-formed, including any implicit conversions to the return type of the function:
To test() { return declval<From>(); }
Arrays can rarely be the destination of implicit conversions, since they can be neither parameter types nor return types. But they are not excluded from temporary materialization conversion.
CodePudding user response:
I don't have a copy of the newest standard, but in [dcl.init.string], there is the paragraph:
If there are fewer initializers than there are array elements, each element not explicitly initialized shall be zero-initialized (8.5).
C .2011§8.5.2¶3
So it is the specified behavior for initializing a char
array of known size with a literal.
CodePudding user response:
For the purposes of overload resolution, it is considered to be an implicit conversion, but one that involves no actual conversions (the identity conversion sequence). See [over.ics.list]/4:
Otherwise, if the parameter type is a character array125 and the initializer list has a single element that is an appropriately-typed string-literal (9.4.2), the implicit conversion sequence is the identity conversion.
125 Since there are no parameters of array type, this will only occur as the referenced type of a reference parameter.
The implicit conversion to array type itself (not a reference to array) seems to be pretty restricted: it's apparently only allowed in a variable definition. Something like static_cast<char[10]>("banana")
won't compile (at least on GCC and Clang).