size_t problems

M

Martin Wells

jacob:
But that is not the point. The point is that you have to take care of
this stuff you see?

Many people (me included) would rather NOT TAKE CARE OF THIS STUFF

Fair enough. Then all you need is a signed integer type whose positive
range is at least that of "size_t". I suppose the Standard could have
provided such a type, but it would probably be horribly inefficient
as, on a lot of systems in anyway, it would entail tagging a byte onto
the end of a size_t. For instance, let's say that size_t is 64-Bit on
a particular system, and that the max register size on this system is
64-Bit. Well we'll need 65 bits if we want a signed type, but this
will have to be implemented under-the-hood as a 64-Bit value
accompanied by a byte to say whether its positive or negative.

The other option was to allow the competent programmer to solve his
problem.

If you're guaranteed to be working with sizes smaller than 32767, then
by all means use int. You might want to you casts in places though if
you're to suppress compiler warnings.

Martin
 
C

CBFalconer

Malcolm said:
You're allowed 32 767 bytes in automatic memory, minimum. However
if the compiler writer has misread the campaign for 64 bit ints as
the "campaign for 64 byte ints", which is possible, even 9 bits
will break.

Where did you get that weird idea? Maybe you should look up the
meaning of CHAR_BIT.
 
C

CBFalconer

Flash said:
.... snip ...

As previously pointed out to you and ignored on several occasions,
nuts and bolts come in LOTS of different sizes. The nuts and bolts
used to hold the engine in your car would not fit in my PDA, the
nuts and bolts in my PDA would not be able to hold your cars
engine in place.

The proposed ISO standard sets all bolt sizes to be 1/4" x 2-56.
:)
 
K

Kelsey Bjarnason

Yes.
It the standards problem. As long as every nut will fit every bolt,
everything is simple. Engineer one says "give me a nut", engineer two
supplies it.

I'm building a watch, the guy next to me is building a 75,000 HP diesel
engine. We share a bin of bolts (and nuts), because bolts (and nuts) are
now standardized, so if I need a bolt - say to clamp down the back of the
movement housing - I reach in and grab one, and when I'm done my watch
weighs 1200 pounds and measures four feet in its smallest dimension.

Yup, sounds good. Every nut fits every bolt, everything is simple.
 
M

Mark McIntyre

Mostly, that group has no developers, just language lawyers, people
that write compilers, etc, and have very specific questions about
paragraph xxx of the standard ...
....
The problem with comp.std.c is that many people there are the same
"regulars" here, so I do not see much difference actually.
....

These two facts cannot both be true, since they're contradictory.
Some discussions are possible. For instance when Mr Heathfield mentioned
in one of those discussions that he missed operator overloading I tried
to argument my position and sent a lengthy message explaining why
this would improve C.

The answer was a boatload of insults from Mr Heathfield

post a reference to the "boatload of insults" which were posted in
comp.std.c
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
T

Tor Rustad

Martin said:
Tor:



You'd many other options. Here's just two:

Option A:

for (j = 7+1; j--; ++k)

Option B:

for (j = 7; j != -1; --j,++k)

When the location of the bug was detected, fixing it wasn't a challenge,
but I wanted a max *readable* solution. Your options, are less readable
IMO. Introducing a signed/unsigned mismatch was no big deal here, the
unsigned value was known to be in the range 0 < x < 129.
 
T

Tor Rustad

jacob said:
But that is not the point. The point is that you have to take care of
this stuff you see?

Many people (me included) would rather NOT TAKE CARE OF THIS STUFF!

AFAIK, it is the first time I have written j >= 0 for an unsigned, so
this is not a frequent case, and will not stop me from using size_t in
the future.

However, it would have been nice if the *compiler* had warned me about
the bug. Does your compiler give a warning in this case? If not, why not
add it?
 
M

Martin Wells

Your options, are less readable IMO.


Yes, I agree that they are.

Introducing a signed/unsigned mismatch was no big deal here, the
unsigned value was known to be in the range 0 < x < 129.


Then your int solution is actually quite good.

What I'm against however, is the use of inappropriate types all the
time even when the max number is not known.

Also, if you're going to be converting from larger integer types to
smaller ones, then I'd advocate using a cast to suppress a compiler
warning so you don't end up with the mess that jacob had. It wouldn't
be a bad idea to do stuff like:

#define i_strlen(x) ( (int)strlen((x)) )

Martin
 
M

Martin Wells

However, it would have been nice if the *compiler* had warned me about
the bug. Does your compiler give a warning in this case? If not, why not
add it?


I've seen a lot of compilers warn about redundant expressions and
statments, reason being that if an expression or statement is
redundant then the programmer probably intended for it to be or mean
something else. It would warn about the following for instance:

int main(void)
{
int x = 7;

x + 4; /* Warning: Redundant statement */
}

Martin
 
C

CBFalconer

Tor said:
.... snip ...

Put me in idiot club then. :-( Here, is the code snippet of a bug I
wrote today:

size_t i, j, k;

[...]

for (i=0, k=1; i<iso->field[P1_BITMAPS].length; i++) {
for (j=7; j>=0; j--,k++) {

j = 7;
do {
....
k++;
} while (0 != j--);
 
K

Keith Thompson

So that's your reason for not posting to comp.std.c.
Mostly, that group has no developers, just language lawyers, people
that write compilers, etc, and have very specific questions about
paragraph xxx of the standard ...

And that's your *new* reason for not posting to comp.std.c, but you
don't acknowledge that your previous reason was invalid.

[...]
The problem with comp.std.c is that many people there are the same
"regulars" here, so I do not see much difference actually.

jacob

P.S. you know that. You read that group.

There's a difference. You know that.
 
P

Peter J. Holzer

Where did you get that weird idea? Maybe you should look up the
meaning of CHAR_BIT.

I haven't seen the program you are discussing here, but from the
description I guess that it contains an automatic variable like

int foo[UCHAR_MAX+1];

If there is a compiler where sizeof int is 64 (64 *byte* int, not 64
*bit* int) and UCHAR_MAX is 511 (CHAR_BIT == 9), then sizeof foo is 64 *
512 == 32768: On byte larger than guarantueed by the standard, so this
may indeed fail (of course an implementor which uses 576 bit ints on a
machine with so little memory that it can't create a 32kB array would be
seriously wacky).

hp
 
P

Peter J. Holzer

[originally it was: size_t i, j, k;]
You'd many other options. Here's just two: [...]
Option B:

for (j = 7; j != -1; --j,++k)

This isn't completely portable. If size_t is smaller than int, j will
wrap around to a positive value != -1. You would have to write:

for (j = 7; j != (size_t)-1; --j,++k)

hp
 
P

Peter J. Holzer


If you want Perl, you know where to find it.

Fair enough. Then all you need is a signed integer type whose positive
range is at least that of "size_t". I suppose the Standard could have
provided such a type, but it would probably be horribly inefficient
as, on a lot of systems in anyway, it would entail tagging a byte onto
the end of a size_t. [...]
The other option was to allow the competent programmer to solve his
problem.

The third option is to restrict the object size to half the
theoretically possible value, i.e. 32767 bytes with 16 bit size_t,
2147483647 with 32 bit size_t and 9223372036854775807 bytes with 64 bit
size_t. No problem for 64 bit systems and not an undue restriction on
most 32 bit systems: Many reserve a rather large part of the address
space or have an unfortunate memory layout, so that you can't get a
single object larger than about 2 GB anyway (and if your problem needs
more than 2 GB today, it probably will need more than 4 GB next year, so
you'd better start planning for that). The real problems were probably
(especially in the late 1980's when the standard was written) with 16
bit systems. Reducing the maximum possible size from 64 kB to 32 kB
would probably have hurt quite a few programs.

hp
 
M

Martin Wells

Peter:
This isn't completely portable. If size_t is smaller than int, j will
wrap around to a positive value != -1. You would have to write:

for (j = 7; j != (size_t)-1; --j,++k)


In writing the code, I thought it so strange for size_t to be anything
smaller than an "unsigned int" that I didn't make allowances for it
being any smaller.

Are you certain that size_t can be smaller than an unsigned int? If
so, that's a little strange.

As an aside, I had originally written it with the cast so that it
would work with any unsigned integer type, but changed it because I
knew I'd have a 20-minute-long discussin afterward with the people who
have phobias of casts, much less redundant casts.

Martin
 
E

Ed Jensen

Keith Thompson said:
And that's your *new* reason for not posting to comp.std.c, but you
don't acknowledge that your previous reason was invalid.

Jacob's "excuses" for not posting to comp.std.c isn't any worse than
some other people's "excuses" for not posting to comp.lang.c.moderated.
 
J

jacob navia

I posted the specifications of operator overloading to
comp.std.c

Now, please go there and let's discuss the TECHNICAL issues and stop the
polemic

OK?
 
K

Kelsey Bjarnason

[snips]

If there is a compiler where sizeof int is 64 (64 *byte* int, not 64
*bit* int) and UCHAR_MAX is 511 (CHAR_BIT == 9), then sizeof foo is 64 *
512 == 32768: On byte larger than guarantueed by the standard, so this
may indeed fail (of course an implementor which uses 576 bit ints on a
machine with so little memory that it can't create a 32kB array would be
seriously wacky).

Ds9k invoked in terminally perverse mode?
 
F

Flash Gordon

jacob navia wrote, On 05/09/07 17:48:
I posted the specifications of operator overloading to
comp.std.c

Now, please go there and let's discuss the TECHNICAL issues and stop the
polemic

OK?

Fine with me. Although the middle of this thread was probably not the
best place to announce that you have done this.
 
P

Peter J. Holzer

Peter:

In writing the code, I thought it so strange for size_t to be anything
smaller than an "unsigned int" that I didn't make allowances for it
being any smaller.

I also consider such an implementation very strange and probably
wouldn't care about in production code (although I might add an
assertion to document (and check) the assumption).

Are you certain that size_t can be smaller than an unsigned int?

I cannot find any requirement in the standard regarding the minimum size
of size_t. It is simply an "unsigned integer type".

I find no plausible scenario where this would make sense for a hosted
implementation, but it could happen for some embedded devices. Consider
a CPU with a word size (integer registers and address bus) of 14 bits.
That's not enough for an int, so an int must use a double word (28
bits). But it's enough for a size_t, since no object can be larger than
16383 bytes. So CHAR_BIT could be 14, sizeof size_t == 1, sizeof short
== sizeof int == 2, and sizeof long == 3.

As an aside, I had originally written it with the cast so that it
would work with any unsigned integer type, but changed it because I
knew I'd have a 20-minute-long discussin afterward with the people who
have phobias of casts, much less redundant casts.

You can't escape discussions in this group :).

hp
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,996
Messages
2,570,238
Members
46,826
Latest member
robinsontor

Latest Threads

Top