Home > Net >  Is initializing char array from string literal considered to be a implicit conversion?
Is initializing char array from string literal considered to be a implicit conversion?

Time:10-12

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.

[conv.general]:

An expression E can be implicitly converted to a type T if and only if the declaration T t=E; is well-formed, for some invented temporary variable t ([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.)

[meta.rel]/5:

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).

  • Related