size_t problems

K

Kenneth Brody

Richard said:
But int s = sizeof(char *) is not broken, even though sizeof() returns
a size_t.

What happens if sizeof(char *) doesn't fit in an int? (Okay, I don't
expect any real world system to exist for which that is true. But,
does the standard say that sizeof must fit in an int? And if so, why
return a size_t?)

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
R

Richard Heathfield

Bart said:
If I have a container that can hold 0 to 12 eggs
and another that can hold (use some imagination) -6 to 6 eggs, it's
easy enough to compare say 4 in one with +3 in the other (the first
will make a bigger omelette).

Let's just say I'm suffering from imaginatrophy, shall we? The problem
here is not the negative value itself, but the comparison between a
value of a type that can store negative values and a value of a type
that cannot. These are fundamentally different concepts.
 
R

Richard Tobin

Richard Heathfield said:
Let's just say I'm suffering from imaginatrophy, shall we? The problem
here is not the negative value itself, but the comparison between a
value of a type that can store negative values and a value of a type
that cannot. These are fundamentally different concepts.

Sizes and array subscripts are naturally connected, and often used
together in expressions. Array subscripts in C can be negative.
strlen() can't return a negative value, but it may make perfect sense
to compare its result with a subscript that can be negative, since it
is the subscript of the nul character at the end of the string.
Suppose s points to some interesting position in the middle of a
string, and s[t] is some other interesting position which may be
before or after s (so t is a signed integer). Why shouldn't I compare
t with strlen(s) to see whether it's before the end of the string?

There would be absolutely no problem using a signed type for sizes if
that type were big enough. Unfortunately, the natural signed type
*isn't* always big enough.

-- Richard
 
C

Charlton Wilbur

RH> Let's just say I'm suffering from imaginatrophy, shall we? The
RH> problem here is not the negative value itself, but the
RH> comparison between a value of a type that can store negative
RH> values and a value of a type that cannot. These are
RH> fundamentally different concepts.

Something I find myself considering frequently: do I have more dollars
in my wallet or in my debit card account? It's impossible for me to
have less than zero dollars in my wallet (although zero is
depressingly frequent), but it's entirely possible, as I have a line
of credit, to have less than zero dollars in my bank account.

The amount of money in my wallet is inherently an unsigned value; the
amount of money in my bank account is inherently a signed value.
Comparisons between them happen several times a week.

Charlton
 
R

Richard Heathfield

Charlton Wilbur said:
RH> Let's just say I'm suffering from imaginatrophy, shall we? The
RH> problem here is not the negative value itself, but the
RH> comparison between a value of a type that can store negative
RH> values and a value of a type that cannot. These are
RH> fundamentally different concepts.

Something I find myself considering frequently: do I have more dollars
in my wallet or in my debit card account? It's impossible for me to
have less than zero dollars in my wallet (although zero is
depressingly frequent), but it's entirely possible, as I have a line
of credit, to have less than zero dollars in my bank account.

But you don't have /any/ dollars in your bank account. What you have is
a number which represents a dollar /balance/ - it is, if you like, the
difference between the number of dollars the bank owes you and the
number of dollars you owe the bank. It can, however, reasonably be
regarded as a monetary amount, and as such can of course be negative.
The number of dollars in your wallet is /also/ a monetary amount, and
monetary amounts can be negative. Of course, the number of dollars in
your wallet cannot be negative, any more than 6 can be negative, even
though 6 is an int and ints can be negative.
 
M

Martin Wells

jacob navia:
Assuming that you have a shred of intelligence, you will be able
to understand this:

That int is used in many other contexts later, for instance
comparing it with other integers.
int i,len = strlen(str);

for (i=0; i<len; i++) {
/// etc

}

The i<len comparison would provoke a warning if len is unsigned...

If I make i unsigned too, then its usage within the loop will provoke
even more problems!


See you're not really looking for a solution at all, but rather a band-
aid to place over the gaping wound.

If you want to trully fix the code, then re-write it PROPERLY.

You might choose "unsigned" over "size_t" if you're EXTREMELY speed-
conscious, even though there'll only be a difference on machines where
"size_t" is bigger than the most efficient integer type. You'll have
to make sure though that the string length will always be within
range. In any way, it should have been written as:

unsigned x = (unsigned)strlen(my_string);

The purpose of the cast would be to suppress a compiler warning.

As for using "int" as a loop counter, I don't see why you'd use a
signed integer type for that purpose (other than "int syndrome" of
course).

Martin
 
M

Martin Wells

Millions of programmers the world over use int as a size store for
strings they know to be only a "few bytes" long. It might not be "right"
now, but there is a huge legacy of it.

And that's perfectly OK if they make sure the number will never be too
high.

However, they'd want a cast to suppress compiler warnings.

Martin
 
B

Ben Pfaff

Martin Wells said:
When used properly it works perfectly.

But that's the problem: if it was used properly, then you
wouldn't have to make the change. The fact that you have to
change it means that related code is likely to make bad related
assumptions.
 
U

user923005

Now that is not fair. Yes, Jacob has peculiar (and many are
unsound) ideas, but that does not make him a troll. He seems to
have co-operated on advertising his compiler, for example, without
specifically acknowledgeing so doing.

There have been other posters who (over time) became more and more
sensible.

In fact, that should happen to all of us, and it should be an ongoing
process (never coming to completion because none of us are perfect).

Now, I sometimes disagree with Jacob, but I think he makes an honest
attempt to communicate most of the time. Though he may often be
'contrary' I would not label him as a troll.

For my way of thinking, a troll has no interest in information. He
just wants to do something controversial and then sit back and laugh
at the reactions. Either that, or they are mentally ill and are
incapable of intelligent exchange of information. In my opinion,
Jacob Navia is not of either sort.
 
U

user923005

Just out of curiosity, what was the rationale behind having strlen()
return size_t instead of "int" or "unsigned int" in the first place?

The result of a sizeof () operator is a size_t.

Can you imagine any object which has a negative size?

A size_t can describe the size of any object allowed by the C
language. An int cannot.

What if objects larger than unsigned are allowed by a compiler
implementation?
It is not unlikely that int and unsigned int are 32 bits on some
implementation on 64 bit hardware.
Would you want to be able to allocate an array of 20 GB if you needed
it? In such an instance, an unsigned integer would not work but a
size_t could work.

Can you imagine a better thing to return than a size_t?

Summary:
An int is a defective return from anything that describes the size of
an object.
An unsigned is a defective return from anything that describes the
size of an object.
A size_t is the perfect return from anything that describes the size
of an object.
I try to always use size_t both for object dimentions and array
addressing (though I admit I am not totally rigorous about it).
 
J

Joe Wright

Richard said:
CBFalconer said:


No, it wasn't.


That's a good four orders of magnitude - almost five - away from being a
nautical mile.
A nautical mile is a minute of arc of the Earth's great circle. About
6,080 feet or 72,960 inches. That would be a 'Pretty' penny indeed.
 
R

Richard Tobin

Kenneth Brody said:
What happens if sizeof(char *) doesn't fit in an int?

Then you should get a different computer.
(Okay, I don't
expect any real world system to exist for which that is true. But,
does the standard say that sizeof must fit in an int? And if so, why
return a size_t?)

No, and it commonly doesn't. But not all programs have to handle
objects that big.

-- Richard
 
C

CBFalconer

Richard said:
There are lots of reasons to assign an unsigned value to an int.
Most notably, so that you can do integer arithmetic on it. Do
you really want all array subscript variables to be size_t? If
so, you'll have to consider casting them if, say, you want to
subtract one from another.

Not if you don't get a negative result. You can easily avoid this
by applying the complex test "if (szt1 > szt2) ... else ...".
 
C

CBFalconer

Richard said:
Bart said:


Let's just say I'm suffering from imaginatrophy, shall we? The
problem here is not the negative value itself, but the comparison
between a value of a type that can store negative values and a value
of a type that cannot. These are fundamentally different concepts.

However we can compare the "count of items in the bins",
eliminating the dependance on what the items actually are. This
corresponds to casting in some form or another, and carries its own
dangers.
 
E

Ed Jensen

user923005 said:
An int is a defective return from anything that describes the size of
an object.

And yet, other programming languages get by -- somehow -- by returning
an integer when asked for the length of a string.
An unsigned is a defective return from anything that describes the
size of an object.

And yet, other programming languages get by -- somehow -- even though
they don't even have unsigned integer types.
A size_t is the perfect return from anything that describes the size
of an object.

I recognize and understand why the range of C types are defined the
way they're defined, but that doesn't minimize the pain when trying to
write 100% portable code.
 

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