On Wed, May 25, 2011 at 4:40 AM, Jan Hudec <b...@ucw.cz> wrote:

> Hello All,
>
> Semantics of operations on integers changed between 3.7.5 and 3.7.6. It
> does
> not seem to be mentioned in change log (http://www.sqlite.org/news.html),
>

4th bullet here:  http://www.sqlite.org/releaselog/3_7_6.html



> though it may affect existing applications:
>
>  * Up to 3.7.5, integer operations are always carried out in 64-bit
> integers
>   and overflow as expected for that type.
>

It turns out that the "expected" behavior does not happen in modern C
compilers.  Overflow of signed integers is undefined behavior in C.  So if
you have a signed integer overflow, it might wrap the result (the "expected"
result) or it might segfault, or it might reformat your hard drive (probably
not, but it could and still comply with the spec!)  Recent compilers will
take advantage of this undefined behavior to take shortcuts with signed
integer arithmetic, meaning that different things happen on different
compilers and with different optimization settings.  On the other hand, we
want SQLite to give the same answer regardless of how it is compiled.  So as
of version 3.7.6, SQLite is careful to avoid signed integer overflows.  We
now require that SQLite work even if compiled using the -fwrapv option in
GCC.

http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html
http://blog.regehr.org/archives/213



>  * From 3.7.6 on, integer operands of *some operations* (left shift being
>   notable exception) are converted to real if the operation would overflow.
>
> I don't think either behaviour is specified anywhere. However, the old
> behaviour was IMO consistent and was very useful for two cases:
>
>  * When working with unsigned numbers on the application side (arithmetic
>   operations except division (/) and right shift (>>) don't consider sign).
>  * To get some bit patterns when doing bitwise operations (since there are
>   & and |, but no negation and no hexadecimal literals).
>
> On the other hand the new behaviour will:
>
>  * Give MIN_INT64 for all operations that overflowed (the application
> expects
>   integer, so will probably read with sqlite3_column_int64 and conversion
> of
>   too large reals *is* specified to return MIN_INT64).
>  * Give inprecise result for cases where the overflows cancel out (e.g.
>   a + b - c where a + b overflows, but a + (b - c) does not.
>
> Would you be so kind and at least visibly document this change, consider
> which behaviour is actually prefered and document the behaviour. Thanks.
>
>
> As for my particular case, I have a database with table (let's call it
> "objects") with large integeral primary key and many other tables refering
> to
> it. And another table (let's call it "sides"), which needs *two* rows for
> each row in "objects". Since "integer primary key" is faster than "primary
> key (object_id, side)" and since the rows are mostly handled independenty
> (and have many other things refer to them), I construct a primary key with:
>
>    object_id | (side << 63)
>
> Now when I need to join "sides" and "objects", I need condition
>
>    object_id = side_id & ~(1 << 63)
>
> but that's not valid syntax. There are two alternatives:
>
>    (1 << 63) - 1  or  -1 - (1 << 63)
>

Surprisingly, the first does *not* work in C - at least not all the time.
The answer is undefined.  It gives the "expected" answer often, especially
when optimizations are disabled.  But if you crank up the optimization on a
recent version of GCC or Clang, you'll likely get something different from
what you expect, unfortunately.


>
> I used the first, because it is more readable to me (while the later is
> exact
> alternative to the bitwise not, it's not common knowledge, because other
> languages do have bitwise not). But it stopped working in 3.7.6 (the later
> still does, so I can convert it, but it's error-prone situation).
>
> Regards,
> Jan
>
> --
>                                                - Jan Hudec <b...@ucw.cz>
>
>
> _______________________________________________
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>



-- 
D. Richard Hipp
d...@sqlite.org
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to