Re: [eigen] Indexes: why signed instead of unsigned?

[ Thread Index | Date Index | More Archives ]

To be honest, I'm somewhat conflicted.
I believe in the credo "say it in the code", which supports using size_t since it is meant for indexing of arrays. However, I also believe firmly in making it as easy to write correct code, which supports using a signed type (because of the unforgiving nature of unsigned types previously discussed ).

The biggest drawback of Eigen simply using "int" in most cases is that it sets a limit of 2^31-1 elements on operations. Are we to the point where this is a real-world issue? Has anyone not been able to use Eigen or had to code around this limit? I rarely deal with more than a few million samples at once. If this limit IS a problem, then how about a typedef for ptrdiff_t inside the Eigen namespace? e.g. Eigen::Integer

-- Mark Borgerding

Benoit Jacob wrote:
Thanks Mark for supporting my position (in favor of signed) with fresh
examples, when I myself was starting to doubt!

What about the other debate, between in (32bit) and ptrdiff_t (same
size as void*) ?


2010/5/11 Mark Borgerding <mark@xxxxxxxxxxxxxx>:
Using unsigned types for indexing is much less forgiving of different styles
of for loops ( as your example shows ). I've been programming since I was
twelve (nearly 30 years now) and I still often write "for" loops that don't
work well with unsigned types. The loops look correct and in most cases
behave correctly.

Here are a few examples that fail with unsigned N:

  for (k=0;k<N-3;k+=4)
     // ... deal with 4 elements at a time.       // This fails
spectacularly with unsigned N<3.  It works with signed N

  while (--N > 0) {
     // fails with unsigned N=0. It works with signed N

Even trickier, there can be latent bugs that only appear when
sizeof(unsigned int) != sizeof(void*) (this one really happened to me)
  unsigned int  smallOffset = N-k
  buf[ largeOffset + smallOffset ]  = 42;
If unsigned N<k then smallOffset wraps around to around 4e9 (with a 32 bit
int).  On a 32 bit OS, the index/dereference of buf wraps back around, doing
what the programmer intended (latent bug).
On a 64 bit OS, this actually has the address space to offset buf by 4e9
elements and fails spectacularly.
If smallOffset and N were signed, then there would be no problem.

-- Mark Borgerding

Benoit Jacob wrote:
There's a new thread on the forum about that (sigh).

Let's settle this once and for all. There are 2 debates:
1) signed or unsigned?
2) int (that is 32 bits) or same-sizeof-as-pointers (e.g. 64bit on
64bit platforms)?

For 2) signed, we could do ptrdiff_t, i guess. Unless you're sure that
'long' is actually on all platforms the size of a pointer. I still
dont know whether 2) matters. Certainly not for cubic-complexity
algorithms (would take forever). But for plain "level 1" operations,
perhaps it's plausible. Feels like we shouldn't arbitrarily restrict
sizes to 32 bits. Opinions?

For 1), I don't know. the forum poster mentions a reasonable way to
write decreasing for loops. It's true that such loops are not too
frequent anyway. I dont know. Asking for opinions. Dont want to impose
upon you a decision made 3 years ago when I was a "noob".

Gael? Hauke? Jitse? Thomas? everybody?


Mail converted by MHonArc 2.6.19+