csharpstandard icon indicating copy to clipboard operation
csharpstandard copied to clipboard

Prohibit stackalloc int[3][1]

Open jskeet opened this issue 1 year ago • 3 comments

In #1211 it looks like stackalloc int[3][1] should be valid by the standard, but Roslyn complains. We've decided it wouldn't do what is probably expected anyway, so it would be better to prohibit it in the standard.

We haven't yet decided on the best approach for this (e.g. in the grammar or as an additional semantic rule in the text).

jskeet avatar Dec 11 '24 20:12 jskeet

Possible strategy: Categorize it as an array creation expression in the grammar.

gafter avatar Dec 11 '24 20:12 gafter

Would it help those who come after us to say something explicit, so that people don't have to try to tease apart whether or not things were blocked by design and what the rationale might have been?

jnm2 avatar Dec 12 '24 20:12 jnm2

@jnm2 Yes, and the proposed solution piggy-backs on such text already in the standard:

Primary expressions are divided between array_creation_expressions and primary_no_array_creation_expressions. Treating array_creation_expression in this way, rather than listing it along with the other simple expression forms, enables the grammar to disallow potentially confusing code such as

object o = new int[3][1];

which would otherwise be interpreted as

object o = (new int[3])[1];

gafter avatar Dec 15 '24 01:12 gafter

We need to see whether https://github.com/dotnet/csharpstandard/pull/1322 solved this. We're not sure.

jskeet avatar Jul 02 '25 19:07 jskeet

Assigned @gafter just to check if this is still an issue.

jskeet avatar Jul 02 '25 19:07 jskeet

I don't think so. This is still an issue, and worse than before. #1322 has been merged, but in https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/grammar.md we have the following:

primary_expression
    : stackalloc_expression
    | element_access
    | array_creation_expression
    | ...
    ;
element_access
    : primary_expression '[' argument_list ']'
    ;

In short, it appears that the parts of the spec that would have forbidden new int[3][1] have been removed from the specification, and cannot be relied on to also forbid stackalloc int[3][1].

gafter avatar Jul 29 '25 23:07 gafter

I don't think so. This is still an issue, and worse than before. #1322 has been merged, but in https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/grammar.md we have the following:

primary_expression : stackalloc_expression | element_access | array_creation_expression | ... ; element_access : primary_expression '[' argument_list ']' ; In short, it appears that the parts of the spec that would have forbidden new int[3][1] have been removed from the specification, and cannot be relied on to also forbid stackalloc int[3][1].

@gafter – #1322 switched from syntactic restriction to semantic restrictions, e.g. in for element_access it now says:

The primary_expression of an element_access may not be an array_creation_expression unless it includes an array_initializer, or a stackalloc_expression unless it includes a stackalloc_initializer.

Followed by a Note explaining this prevent these forms. The preamble in #1322 explains why this was done.

Hopefully the restrictions are all there and correct.

Nigel-Ecma avatar Jul 29 '25 23:07 Nigel-Ecma

@gafter: Please could you check again with the context of @Nigel-Ecma's comment?

jskeet avatar Sep 03 '25 20:09 jskeet