GCC Undefined Behavior Sanitizer

via Digitalmars-d digitalmars-d at puremagic.com
Sun Oct 19 04:24:04 PDT 2014


On Sunday, 19 October 2014 at 10:22:37 UTC, monarch_dodra wrote:
> Speed: How so?

All kind of situations where you can prove that "expression1 > 
expression2" holds, but have no bounds on the variables.

> Portability: One issue to keep in mind is that C works on 
> *tons* of hardware. C allows hardware to follow either two's 
> complement, or one's complement. This means that, at best, 
> signed overflow can be implementation defined, but not defined 
> by spec. Unfortunately, it appears C decided to outright go the 
> undefined way.

I think you might be able to make it defined like this:

1. overlflow is illegal and should not limit reasoning about 
monoticity

2. after overflow accessing a derived result can lead to a value 
where the overflow either lead to a higher bit representation 
which was propagated or lead to a value which was truncated.

This is slightly different from "undefined".

:-)

> Correctness: IMO, I'm not even sure. Yeah, use int for numbers, 
> but stick to size_t for indexing. I've seen too many bugs on 
> x64 software when data becomes larger than 4G...

Sure, getting C types right and correct is tedious. The type 
system does not help you a whole lot. And D and C++ does not make 
it a lot better. Maybe the implicit conversions is a bad thing.

I machine language there is often no difference between a signed 
and unsigned instructions which can be handy, but the typedness 
of multiplication is actually  better than in C languages "u64 
mul(u32 a,u32 b)". Multiplication over int is dangerous!

Before compilers got good at optimization I viewed C as an 
annoying assembler. I assumed wrapping behaviour and wanted an 
easy way to reinterpret_cast between ints and uints (in C it gets 
rather ugly).

These days I take the view that programmers should be explicit 
about "bit-crushing" operations. Maybe even for multiplication. 
If you are forced to explicitly truncate() when the compiler 
fails to rule out overflow then the problem areas also become 
more visible in the source code:

"uint r = a*b/N" might overflow badly even if r is large enough 
to hold the result.

"uint r = truncate(a*b/N)" makes you aware that you are on thin 
ice.


More information about the Digitalmars-d mailing list