Richard, At 13:07 25/05/2011, you wrote:
>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. You're certainly right about your point and I'm not going to argue about the grounds of the C standard. Nonetheless, the resulting behavior is surprising: V:\Bin>sqlite3 SQLite version 3.7.6.3 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> .load unifuzz.dll sqlite> CREATE TABLE if not exists "overflow" ( ...> "Test" INTEGER PRIMARY KEY AUTOINCREMENT, ...> "Operation" CHAR, ...> "IntValue" INTEGER, ...> "Type" CHAR, ...> "Hexa" CHAR); sqlite> sqlite> CREATE TRIGGER if not exists "trInsTest" ...> AFTER INSERT ...> ON "overflow" ...> BEGIN ...> update overflow set type = typeof(intvalue), hexa = hexw(intvalue); ...> END; sqlite> delete from overflow; sqlite> insert into overflow (operation, intvalue) values ('initial value MAX_INT', 9223372036854775807); sqlite> insert into overflow (operation, intvalue) values ('- MAX_INT', - (select intvalue from overflow where test = 1)); sqlite> insert into overflow (operation, intvalue) values ('MAX_INT + 1', (select intvalue from overflow where test = 1) + 1); sqlite> insert into overflow (operation, intvalue) values ('- MAX_INT - 1', - (select intvalue from overflow where test = 1) - 1); sqlite> select * from overflow; 1|initial value MAX_INT| 9223372036854775807|integer|7FFFFFFFFFFFFFFF 2|- MAX_INT |-9223372036854775807|integer|8000000000000001 3|MAX_INT + 1 |9.22337203685478e+18|real |8000000000000000 4|- MAX_INT - 1 |-9223372036854775808|integer|8000000000000000 The function hexw(x) is from the loaded extension and simply returns x as an hex string, as you can see. It is just there to make the point clearer: test 3 and test 4 produce the same content but distinct values from distinct types. That can make some applications choke. I decided to avoid any early conversion possibly made by the statement parser and instead of typing literal values as 9223372036854775807 + 1, I retrieved the value as a subselect. Since integer overflow is a concern and given that no standard way of dealing with it consistently is available over the millions of possible targets, wouldn't it be more consistent to have a build-time option ERR_ON_INT_OVERFLOW causing SQLite to return an error in case of integer overflow? _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users