-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[dcl.init.string] Clarify syntactic forms of initializers that are considered as string literals #661
Comments
The rules seem pretty clear to me; [dcl.init.general] p16.3 refers to string-literal (grammar non-terminal), which leaves no room for parentheses. Similarly, [dcl.init.list] p3.3 handles the brace-enclosed case, also referring to the grammar non-terminal string-literal. I'm not seeing how this could be read as allowing parentheses. |
@jensmaurer I do agree, it looks like it is not allowed, but it does seem like most of the implementations accept the "controversial" forms as an extension. It does indeed look like it is used in the wild: I am not coming up with much background on where this extension came from though. |
@shafik , half of those hits (approximately) appear to be the same (cloned) code from the clang test suite. Also, C23 doesn't mention optional parentheses, either. It would be good if we could align the C++ answer with the C answer, I think. |
Shouldn't the wording in [expr.prim.paren] apply here?
Here is an example of this being applied elsewhere:
All compilers I know of accept code like C23 also has similar text which states that a parenthesized expression has the same semantics as the expression which it parenthesizes (see 6.5.2p6). Also as I discovered earlier while making a bug report to GCC about this, GCC accepts using |
Thanks. But it seems that when the grammar non-terminal initializer corresponds to |
Right. We had wording issues in that area in the past. So, p16.3 has a genuine bug as far as an initializer can never be a string-literal, grammatically. This argument does not apply for a brace-enclosed string-literal, though; I think those are properly handled by dcl.init.list p3.3. |
Full name of submitter (unless configured in github; will be published with the issue): Jiang An
Reference (section label): [dcl.init.general], [dcl.init.string]
[dcl.init.general] p16.3:
[dcl.init.string] p1
The syntactic forms of such initializers are not very clear and there's implementation divergence.
"Good" forms:
char a[] = "foo";
- accepted by all known implementations, and clarified to be valid in notes;char a[]("foo");
- accepted by all known implementations;char a[]{"foo"};
- accepted by all known (C++11 and later) implementations;char a[] = {"foo"};
- accepted by all known (C++11 and later) implementations.Controversial forms with additonal parentheses:
char a[] = ("foo");
- diagnosed by GCC (and EDG & Comeau per clang ("foo") accepted as char[] initializer llvm/llvm-project#8418); silently accepted by other implementations;char a[](("foo"));
- likely same as above;char a[]{("foo")};
- likely same as above;char a[] = {("foo")};
- likely same as above.Weird forms with additional braces:
char arr[]{{"foo"}};
- accepted by MSVC and rejected by others;char arr[] = {{"foo"}};
- same as above.It seems that we should clarify the permitted syntactic forms, which should include "good" and controversial forms and exclude weird forms.
Link to reflector thread (if any):
Issue description:
Suggested resolution:
The text was updated successfully, but these errors were encountered: