rsmith added inline comments.
================ Comment at: clang/test/CXX/drs/dr14xx.cpp:411-414 + void f(const char[4]); + void f(const wchar_t[4]); + void f(const char16_t[4]); + void f(const char32_t[4]); ---------------- Mordante wrote: > rsmith wrote: > > These should presumably be references to arrays, rather than arrays, or the > > parameter type is as if you wrote (for example) `void f(const char *)`, > > which shouldn't get the special treatment here. > > > > [over.ics.list]p4 mentions this in its footnote: > > > > "Otherwise, if the parameter type is a character array [Footnote: Since > > there are no parameters of array type, this will only occur as the > > referenced type of a reference parameter.] and the initializer list has a > > single element that is an appropriately-typed string-literal (9.4.3), the > > implicit conversion sequence is the identity conversion." > Ah I missed that footnote. I reread the standard and can you confirm some > cases? > ``` > namespace A { > void f(const char(&)[4]); > void g() { f({"abc"}); } > } > namespace B { > void f(const char(&&)[4]); > void g() { f({"abc"}); } > } > ``` > both should work and with P0388 the array without bounds will also work. > > I ask since this is my interpretation of the standard, but it seems there's a > difference between implementations and `void f(const char(&&)[4]);` fails for > "abc" but works for "ab". > It seems ICC and consider "abc" an lvalue in this case and not when using > "ab". > > Here's a gotbolt link with the examples https://godbolt.org/z/r1TKfx That's a really interesting example :) The initializer is a list containing an lvalue of type `const char[4]`. Per [dcl.init.list]/3.9 and /3.10, the behavior depends on whether the referenced type is reference-related to `const char[4]` -- if so, then the reference can only bind directly and a `&&` reference will be invalid, because it's binding an rvalue reference to an lvalue, and if not, then we create an array temporary and the `&&` binding is fine. Per [dcl.init.ref]/4, `const char[???]` is reference-related to `const char[4]` if they are similar types, and per [conv.qual]/2, the types are similar if `???` is omitted or `4`, and not similar otherwise. So: * `const char (&&r)[4] = {"abc"}` is ill-formed (types are the same, binds rvalue reference to lvalue) * `const char (&&)[] = {"abc"}` is ill-formed (types are similar, binds rvalue reference to lvalue) * `const char (&&r)[5] = {"abc"}` is OK (types are not similar, creates temporary) That seems like a very surprising outcome to me. Perhaps we should probably ignore array bounds entirely when determining whether two types are reference-related. I'll take this to CWG for discussion. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D87561/new/ https://reviews.llvm.org/D87561 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits