Glynn Clements wrote:
Markus Metz wrote:
[...] An integer literal without a
trailing suffix is an "int". Using a larger type to hold the value
where necessary is a gcc extension. Other compilers may simply
truncate the value to an int, even if off_t is 64 bits.
The latest change:
#define OFF_T_TEST 0x0102030405060708LL
will fail to compile with a compiler which doesn't have long long int.
Both the definition and use of OFF_T_TEST need to be conditionalised
with "#ifdef HAVE_LONG_LONG_INT".
OK. But on Linux 32 without LFS I get
port_init.c:217: warning: overflow in implicit constant conversion
at compile time because long long int is available but sizeof(off_t) =
4. Portability and its test is ok because OFF_T_TEST is not used in this
case.
Making the conversion explicit would eliminate the warning:
u_o = (off_t) OFF_T_TEST;
OK.
[...]
A 64-bit system might have a 64-bit off_t
but no "long long" type. We really need to have autoconf use define
SIZEOF_LONG etc in config.h (AC_CHECK_SIZEOF macro), so that we can
use e.g.:
#if SIZEOF_LONG == 8
#define LONG_LONG_TEST 0x0102030405060708L
#elif defined(HAVE_LONG_LONG_INT)
#define LONG_LONG_TEST 0x0102030405060708LL
#endif
You can take it from gdal.
I still see:
719: s[top].sn.branch[j].child.id =
720: (int)s[top].childpos[j];
754: s[top].sn.branch[j].child.id =
755: (int)s[top].childpos[j];
Also:
1011: if (!shcb((int)s[top].sn.branch[i].child, cbarg)) {
A narrowing cast always brings up the question of "what if the value
won't fit in the destination type"?
Am I missing something, or is childpos[j] *always* an "int"?
On level 0, it is always an int. It's the ID of the rectangle passed to
int RTreeInsertRect(struct Rect *r, int tid, struct RTree *t)
as tid. That applies to all three cases above.
I am writing out the rectangle ID as off_t although it is int and have
to read it as off_t then cast it to int again when loading the sidx file
to memory for updating. Of course I could also write the ID as int and
read it as int, then there would be no type casting, at the cost of one
more if ... else ... .
If so,
why is it stored in the file as an off_t?
On higher levels (RTree internal nodes), it is the position in file of
the child nodes of a node. For large sidx files, off_t is needed. The
corresponding line in spindex_rw.c is
668 s[top].pos[s[top].branch_id - 1] = nextfreepos;
where I set the node positions in file as off_t.
This is related to the use of union Child: on level 0, int id is used,
on higher levels, struct Node *ptr is used.
So it's a case of simplifying the sidx file I/O?
Yes, partly my laziness. Took me ages to get that particular post-order
traversal right.
That's reasonable enough. But, personally, I would:
1. Make the pos and childpos fields unions (int/off_t).
That's now easy, similar to the union in rtree.
2. Add an explicit range check before casting the off_t read from the
file to an int.
That should only be necessary if there is reason to suspect that the
sidx file is not read properly. Hmm, actually that would be a good check
for exactly that.
An assert() would suffice; the main purpose is to
answer the "what if it doesn't fit in an int?" question for the
benefit of anyone trying to read that code.
Only works if off_t_size = 8 is both available and used, otherwise it
will obviously always fit into an int.
The answer would be that the programmer wrote bad code with bugs because
it should never happen that it doesn't fit into an int.
Markus M
_______________________________________________
grass-dev mailing list
[email protected]
http://lists.osgeo.org/mailman/listinfo/grass-dev