New string types and deprecated conversion
7.3.3 [conv.array]
Alisdair Meredith

Created on 2008-04-21.00:00:00 last changed 144 months ago


Date: 2009-10-15.00:00:00

[Voted into WP at October, 2009 meeting.]

Date: 2009-09-15.00:00:00

Proposed resolution (September, 2009):

  1. Remove 7.3.3 [conv.array] paragraph 2:

  2. A string literal (5.13.5 [lex.string]) with no prefix, with a u prefix, with a U prefix, or with an L prefix can be converted to an rvalue of type “pointer to char”, “pointer to char16_t”, “pointer to char32_t”, or “pointer to wchar_t”, respectively. In any case, the result is a pointer to the first element of the array. This conversion is considered only when there is an explicit appropriate pointer target type, and not when there is a general need to convert from an lvalue to an rvalue. [Note: this conversion is deprecated. See Annex Annex D [depr]. —end note] For the purpose of ranking in overload resolution ( [over.ics.scs]), this conversion is considered an array-to-pointer conversion followed by a qualification conversion (7.3.6 [conv.qual]). [Example: "abc" is converted to “pointer to const char” as an array-to-pointer conversion, and then to “pointer to char” as a qualification conversion. —end example]
  3. Delete the indicated text from the third sub-bullet of the first bullet of paragraph 3 of [over.ics.rank]:

    • S1 and S2 differ only in their qualification conversion and yield similar types T1 and T2 (7.3.6 [conv.qual]), respectively, and the cv-qualification signature of type T1 is a proper subset of the cv-qualification signature of type T2, and S1 is not the deprecated string literal array-to-pointer conversion (4.2). [Example: ...

  4. Delete the note from 14.2 [except.throw] paragraph 3 as follows:

  5. A throw-expression initializes a temporary object, called the exception object, the type of which is determined by removing any top-level cv-qualifiers from the static type of the operand of throw and adjusting the type from “array of T” or “function returning T” to “pointer to T” or “pointer to function returning T”, respectively. [Note: the temporary object created for a throw-expression that is a string literal is never of type char*, char16_t*, char32_t*, or wchar_t*; that is, the special conversions for string literals from the types “array of const char”, “array of const char16_t”, “array of const char32_t”, and “array of const wchar_t” to the types “pointer to char”, “pointer to char16_t”, “pointer to char32_t”, and “pointer to wchar_t”, respectively (7.3.3 [conv.array]), are never applied to a throw-expression. —end note] The temporary is an lvalue...
  6. Change the discussion of 5.13.5 [lex.string] in C.6.2 [diff.lex] as follows:

  7. Change: String literals made const
    The type of a string literal is changed... “array of const wchar_t.”

        char* p = "abc";   // valid in C, invalid in C++


    Difficulty of converting: Simple syntactic transformation, because string literals can be converted to char*; (7.3.3 [conv.array]). The most common cases are handled by a new but deprecated standard conversion Syntactic transformation. The fix is to add a cast:

      char* p = "abc";                // valid in C, deprecated in C++
      char* q = expr ? "abc" : "de";  // valid in C, invalid in C++
      void f(char*) {
          char* p = (char*)"abc";  // cast added
          f((char*)"def");         // cast added
  8. Delete _N3000_.D.4 [depr.string]:

  9. D.4 Implicit conversion from const strings [depr.string]

    The implicit conversion from const to non-const qualification for string literals (7.3.3 [conv.array]) is deprecated.

Date: 2009-07-15.00:00:00

Notes from the July, 2009 meeting:

The CWG reached consensus that the deprecated conversion should be removed altogether.

Date: 2008-09-15.00:00:00

Notes from the September, 2008 meeting:

The CWG agreed that the deprecated conversion should continue to apply to the literals to which it applied in C++ 2003. Consensus was not reached regarding whether it should apply only to those literals or to all the new literals as well, although it was agreed that the current situation in which it applies to some, but not all, of the new literals is unacceptable.

Date: 2008-08-15.00:00:00

Additional discussion (August, 2008):

The removal of this conversion for current string literals would affect overload resolution for existing programs. For example,

    struct S {
        S(const char*);
    int f(char *);
    int f(X);
    int i = f("hello");

If the conversion were removed, the result would be a quiet change in behavior. Another alternative to consider would be a required diagnostic (without making the program ill-formed).

Date: 2009-03-23.00:00:00
N2800 comment DE 4

The deprecated conversion from string literal to pointer to (non-const) character in 7.3.3 [conv.array] paragraph 2 has been extended to apply to char16_t and char32_t types, but not to UTF8 and raw string literals. Is this disparity intentional? Should it be extended to all new string types, reverted to just the original character types, or revoked altogether?

Additional places in the Standard that may need to change include 14.2 [except.throw] paragraph 3 and [over.ics.rank] paragraph 3.

Date User Action Args
2010-03-29 00:00:00adminsetstatus: dr -> cd2
2009-11-08 00:00:00adminsetmessages: + msg2429
2009-11-08 00:00:00adminsetstatus: tentatively ready -> dr
2009-09-29 00:00:00adminsetstatus: open -> tentatively ready
2009-08-03 00:00:00adminsetmessages: + msg2211
2009-03-23 00:00:00adminsetstatus: review -> open
2008-10-05 00:00:00adminsetmessages: + msg1764
2008-08-25 00:00:00adminsetmessages: + msg1747
2008-06-29 00:00:00adminsetmessages: + msg1691
2008-06-29 00:00:00adminsetstatus: open -> review
2008-04-21 00:00:00admincreate