negative unsigned value?

200 views
Skip to first unread message

oju...@gmail.com

unread,
May 22, 2017, 12:42:16 PM5/22/17
to golang-nuts
The other day a coworker called me to show a piece of my own code. I confess I got a little embarassed. The code was something like this:

func f(a, b uint){
// ...
dif := a - b
if (dif < 0) {
// do stuff
}
}

As it happens, "stuff" was never done.

I expected the compiler to flag that comparison as an error ("You are testing to see if an unsigned value is negative. Please go back to school.")

So I tried to code the same comparison in C and compiled using TCC, GCC and Microsoft compilers. Then did the same with C++ using GCC, Microsoft. Finally I tried in Pascal using the Free Pascal compiler. To my surprise only Pascal issued a warning. To be fair, MS compiler issued a warning as well, but only after I changed the project warning level to maximum.

I imagine there is a really good reason for compilers not to flag this as an error, but I don't have a clue. Someone can tell me why this is so?


Ian Lance Taylor

unread,
May 22, 2017, 8:19:22 PM5/22/17
to oju...@gmail.com, golang-nuts
GCC will issue a warning for C or C++ code if you use the
-Wtype-limits option. This option is also turned on by -Wextra. The
warning is not enabled by default because reasonable code using
preprocessor macros or templates can cause false positive warnings.

In the case of Go the issue is more that the compiler doesn't generate
warnings. Rejecting an unsigned comparison with zero would be a
language change. It might be reasonable to add a vet check for this,
although I don't know that it occurs often enough to make the check
worth it.

Ian

Caleb Spare

unread,
May 22, 2017, 8:21:56 PM5/22/17
to JuciÊ Andrade, golang-nuts
FYI staticcheck has this check.

https://github.com/dominikh/go-tools/tree/master/cmd/staticcheck

On Mon, May 22, 2017 at 9:41 AM, <oju...@gmail.com> wrote:
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Michael Jones

unread,
May 22, 2017, 8:50:55 PM5/22/17
to Ian Lance Taylor, oju...@gmail.com, golang-nuts

On Mon, May 22, 2017 at 5:19 PM, Ian Lance Taylor <ia...@golang.org> wrote:
Rejecting an unsigned comparison with zero would be a
language change.

yes, but it is not just a comparison with zero, it is a "is it less than zero, which it cannot possibly be since it is unsigned" so therefore it would be enforcing a rule than no correct program can violate. This is the kind of scenario under which other tweaks have gone in...


--
Michael T. Jones
michae...@gmail.com

John Souvestre

unread,
May 22, 2017, 8:53:58 PM5/22/17
to golan...@googlegroups.com

That’s what I would say, too.  If there is no legal way that it can be used, then it’s use must be illegal – hence fit for detection.

 

John

    John Souvestre - New Orleans LA

--

Ian Lance Taylor

unread,
May 22, 2017, 9:00:06 PM5/22/17
to Michael Jones, oju...@gmail.com, golang-nuts
True, but I think some of those tweaks have proven to be problematic.
I'm thinking in particular of the ones that changed constant division
by zero to be a compile time error. Basically, it's only a problem if
the code is executed. Changing this code to be a compile-time error
means that, for example, code generators need workarounds just to
avoid compile-time errors for code that doesn't matter.

Ian

Michael Jones

unread,
May 22, 2017, 11:22:30 PM5/22/17
to Ian Lance Taylor, oju...@gmail.com, golang-nuts
...as always, a pragmatic and informed response. Thanks.

oju...@gmail.com

unread,
May 23, 2017, 7:13:28 AM5/23/17
to golang-nuts
Now I understand it.
Thank you, guys.

Val

unread,
May 23, 2017, 11:27:26 AM5/23/17
to golang-nuts
FWIW, consider first that :

if false {
  foo
()
  bar
()
}

is legal (and sometimes recommended by autorities, as opposed to momentarily commenting out a block, and struggling with unused vars);
and second that :

func log(msg string, level uint) {
 
if level < appLevel {
    triggerBigNetworkLogTool
(msg)
 
}
}

is legal and useful, even if appLevel happens to be a uint constant with value 0. See https://play.golang.org/p/nGbELUdvvu

The current policy seems to be: a unused variable is always regarded as a compilation error, but unreachable code (dead code) is never a compilation error.

Val

unread,
May 23, 2017, 11:42:27 AM5/23/17
to golang-nuts
My initial code was sloppy, sorry about that.  But you get the idea: testing if uint is "less than zero" is sometimes legit.

func log(msg string, level uint) {
 
if level < appLevel {

   
return
 
}
 
triggerBigNetworkLogTool(msg)
}

Reply all
Reply to author
Forward
0 new messages