question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Casting a negative literal value to nint or nuint requires parentheses

See original GitHub issue

Take the following sample code:

public class C {
    uint x = unchecked((uint)-1);      // Ok
    uint y = unchecked((uint)(-1));    // Ok - Suggests removing unnecessary parentheses

    nuint z = unchecked((nuint)-1);    // CS0119 and CS0075
    nuint w = unchecked((nuint)(-1));  // Ok
}

https://sharplab.io/#v2:EYLgtghgzgLgpgJwDQxASwDYB8ACBmAAhwCYCBhAgbwFgAoAhggVzQDsYCAPAgXmdYDGACzgCA1nAAmACmkt2ASgC0ARgUBuRowD02ggHkxdLfI4BPXv2GiJMuWxgLpqhRq26DYgkoIBlJgDmAXCwUAQIcGAA9gBubAH8rKIhUBAIFgAOaXDsIlAhdMaMrKYEAF6WTIIi4lKyJQ7Kapo6emS+AAwqKgCcBBCskuSdHQDsAKxFDA3sBADuldU2ddIzjs5qbgQehnQAvkA

I would expect nuint (and nint) to also allow casting without surrounding the negative integer literal with parentheses.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:7 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
alrzcommented, Jul 27, 2020

Because parser doesn’t know if type is actually a type or expression at parse time, so that is parsed as a binary operator with a parenthesized lhs rather than a cast. I think that’s why CS0075 exists after all, as a hint when the identifier determined to be a type.

On the other hand, when a keyword is used, it is parsed as a cast from get-go – there’s no way uint could be an expression. Note this is not about primitive types themselves, (Int32)-1 has the same ambiguity and yields an error. It must be a keyword.

If the cast operator had a higher precedence than a parenthesized expression (which in turn, defined under “primary expressions”), it could work but that is just not how the grammar is specified. If possible at all, it would have need a lot of lookaheads and does not simply fit into other production rules.

0reactions
cstoncommented, Jul 28, 2020

Thanks @alrz for the detailed explanation.

nint and nuint are identifiers rather than keywords so the current behavior is expected.

Closing as “by design”.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why isn't the C# compiler able to cast a literal negative ...
To cast a negative value, you must enclose the value in parentheses If you are casting using a keyword that identifies a predefined...
Read more >
C# Error CS0075 – To cast a negative value, you must ...
Error CS0075 To cast a negative value, you must enclose the value in parentheses. This is because the expression (EmploymentType) -1 is not...
Read more >
Native sized integers - C# 9.0 draft feature specifications
This feature specification describes native sized integers, which are integer types that use the processor's natural integral types.
Read more >
C# compiler breaking changes since C# 10
In Visual Studio 17.3, the compiler requires spaces before the first parenthesis, the character offset, and the file name.
Read more >
4. Advanced C# - C# 10 in a Nutshell [Book]
A delegate instance literally acts as a delegate for the caller: the caller invokes the delegate, and then the delegate calls the target...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found