Hacker News new | ask | show | jobs
by seoulbigchris 590 days ago
I think why this has always stuck in my craw is that a compiler can complain if the result and operands aren't the same size. But if they ARE the same size, the compiler doesn't similarly complain "your result may overflow the destination variable". If it did, all calculations would be flagged. Imagine a strict clerk in a government office who approves vital documents based solely on whether the paper size and ink color are correct, regardless of the documents' content.

I'm not saying the status-quo is wrongheaded, and I see no obvious way to solve it -- just an observation.

1 comments

> But if they ARE the same size, the compiler doesn't similarly complain "your result may overflow the destination variable"

Pretty much any production compiler can do this. They can also warn when you truncate without doing so explicitly. Where I work, for certain projects, all C++ compilation does both of these, forcing programmers to explicitly cast into size to show they made a careful consideration of sizes.

Other places guarantee integers operate mod n, others guarantee integers grow as needed (e.g., Python).

That people don't learn the numerics of their platform is not the problem of the language or compiler. Using languages that are closer to the hardware means less hand holding when developing code, whether it's memory, numerics, files, or any part where one needs to pay attention and complexity increases.

> Pretty much any production compiler can do this.

I'm curious how a compiler could know this at compile time? If you mean a runtime checking feature, I get it. I'm referring to an example statement like `ix = ia + ib` where all three are, say, u8 integers.

EDIT: I will agree in some situations, the compiler could deduce that a certain equation like above would or would not ever overflow, by context. But for the general case, I don't see how.

You wrote

> But if they ARE the same size, the compiler doesn't similarly complain "your result may overflow the destination variable"

Adding two N bit unsigned integers together can require N+1 bits for the answer. So the compiler, if you add two intN and store into an intN, will warn you that "your result may overflow the destination variable". This is trivial since the compiler knows the types of all the variables in most all programming languages.

Plenty of compilers also use theorem proving to ensure some things do not overflow, so they can optimize accordingly. Thus, in the follow type of program

    int arr[10];
    for (int i = 0; i < 10; ++i)
       arr[i] = i;
The compiler, in languages where arrays are bounds checked, can deduce with certainly that arr is not out-of-bounds here, and can remove costly bounds checking.

But if you have

      int arr[10];
      func setLen(int len)
          for (int i = 0; i < len; ++i)
              arr[i] = i;
Would need bounds checking given only this snippet. But there's more. If the program can prove that setLen is never called (or callable) with len > 10, then once again it can remove the bounds checking.

Modern compilers do an every increasing amount of amazing things to make all this work transparently.