Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #17117 > unrolled thread
| Started by | Robert Hayes <rhyes80@gmail.com> |
|---|---|
| First post | 2012-02-11 11:21 -0800 |
| Last post | 2012-02-11 17:34 -0800 |
| Articles | 20 on this page of 56 — 22 participants |
Back to article view | Back to comp.lang.c
return -1 using size_t??? Robert Hayes <rhyes80@gmail.com> - 2012-02-11 11:21 -0800
Re: return -1 using size_t??? Shao Miller <sha0.miller@gmail.com> - 2012-02-11 15:00 -0500
Re: return -1 using size_t??? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-11 23:24 +0000
Re: return -1 using size_t??? Jeffrey R <joeff@nospam.com> - 2012-02-11 19:58 +0000
Re: return -1 using size_t??? Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-02-11 15:11 -0500
Re: return -1 using size_t??? Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-02-11 15:07 -0500
Re: return -1 using size_t??? Robert Hayes <rhyes80@gmail.com> - 2012-02-11 12:42 -0800
Re: return -1 using size_t??? Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-02-11 13:19 -0800
Re: return -1 using size_t??? Keith Thompson <kst-u@mib.org> - 2012-02-11 17:10 -0800
Re: return -1 using size_t??? Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-02-12 03:48 -0800
Re: return -1 using size_t??? Keith Thompson <kst-u@mib.org> - 2012-02-12 04:04 -0800
Re: return -1 using size_t??? Jeffrey R <joeff@nospam.com> - 2012-02-11 22:25 +0000
Re: return -1 using size_t??? Devil with the China Blue Dress <chine.bleu@yahoo.com> - 2012-02-11 14:36 -0800
Re: return -1 using size_t??? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-11 23:17 +0000
Re: return -1 using size_t??? Jeroen Mostert <jmostert@xs4all.nl> - 2012-02-11 23:46 +0100
Re: return -1 using size_t??? pete <pfiland@mindspring.com> - 2012-02-11 19:18 -0500
Re: return -1 using size_t??? Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-02-12 08:38 -0500
Re: return -1 using size_t??? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-11 23:32 +0000
Re: return -1 using size_t??? pete <pfiland@mindspring.com> - 2012-02-11 19:15 -0500
Re: return -1 using size_t??? Ralph Spitzner <rasp@spitzner.org> - 2012-02-13 13:51 +0100
Re: return -1 using size_t??? Devil with the China Blue Dress <chine.bleu@yahoo.com> - 2012-02-11 12:40 -0800
Re: return -1 using size_t??? Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-02-11 17:02 -0500
Re: return -1 using size_t??? Devil with the China Blue Dress <chine.bleu@yahoo.com> - 2012-02-11 14:11 -0800
Re: return -1 using size_t??? Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-02-11 17:21 -0500
Re: return -1 using size_t??? Devil with the China Blue Dress <chine.bleu@yahoo.com> - 2012-02-11 14:31 -0800
Re: return -1 using size_t??? Willem <willem@toad.stack.nl> - 2012-02-11 22:52 +0000
Re: return -1 using size_t??? Jens Gustedt <jens.gustedt@loria.fr> - 2012-02-12 00:20 +0100
Re: return -1 using size_t??? Devil with the China Blue Dress <chine.bleu@yahoo.com> - 2012-02-12 09:21 -0800
Re: return -1 using size_t??? Keith Thompson <kst-u@mib.org> - 2012-02-12 12:27 -0800
Re: return -1 using size_t??? Jeroen Mostert <jmostert@xs4all.nl> - 2012-02-12 22:17 +0100
Re: return -1 using size_t??? Devil with the China Blue Dress <chine.bleu@yahoo.com> - 2012-02-12 15:10 -0800
Re: return -1 using size_t??? Nick Keighley <nick_keighley_nospam@hotmail.com> - 2012-02-13 03:11 -0800
Re: return -1 using size_t??? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-12 23:25 +0000
Re: return -1 using size_t??? Jeroen Mostert <jmostert@xs4all.nl> - 2012-02-13 07:46 +0100
Re: return -1 using size_t??? Ike Naar <ike@sverige.freeshell.org> - 2012-02-13 10:27 +0000
Re: return -1 using size_t??? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-13 12:36 +0000
Re: return -1 using size_t??? Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2012-02-13 10:26 -0700
Re: return -1 using size_t??? Ike Naar <ike@iceland.freeshell.org> - 2012-02-14 00:18 +0000
Re: return -1 using size_t??? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-14 00:29 +0000
Re: return -1 using size_t??? Devil with the China Blue Dress <chine.bleu@yahoo.com> - 2012-02-13 16:37 -0800
Re: return -1 using size_t??? Angel <angel+news@spamcop.net> - 2012-02-13 11:47 +0000
Re: return -1 using size_t??? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-13 12:54 +0000
Re: return -1 using size_t??? Angel <angel+news@spamcop.net> - 2012-02-13 14:30 +0000
Re: return -1 using size_t??? Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2012-02-22 01:53 +0200
Re: return -1 using size_t??? James Kuyper <jameskuyper@verizon.net> - 2012-02-13 12:11 -0500
Re: return -1 using size_t??? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-13 17:28 +0000
Re: return -1 using size_t??? James Kuyper <jameskuyper@verizon.net> - 2012-02-13 13:08 -0500
Re: return -1 using size_t??? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-13 23:06 +0000
Re: return -1 using size_t??? William Ahern <william@wilbur.25thandClement.com> - 2012-02-13 14:39 -0800
Re: return -1 using size_t??? Keith Thompson <kst-u@mib.org> - 2012-02-13 14:59 -0800
Re: return -1 using size_t??? Jens Gustedt <jens.gustedt@loria.fr> - 2012-02-12 22:17 +0100
Re: return -1 using size_t??? Devil with the China Blue Dress <chine.bleu@yahoo.com> - 2012-02-12 15:06 -0800
Re: return -1 using size_t??? Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-02-12 18:12 -0500
Re: return -1 using size_t??? Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2012-02-22 02:15 +0200
Re: return -1 using size_t??? Barry Schwarz <schwarzb@dqel.com> - 2012-02-11 14:27 -0800
Re: return -1 using size_t??? Keith Thompson <kst-u@mib.org> - 2012-02-11 17:34 -0800
Page 1 of 3 [1] 2 3 Next page →
| From | Robert Hayes <rhyes80@gmail.com> |
|---|---|
| Date | 2012-02-11 11:21 -0800 |
| Subject | return -1 using size_t??? |
| Message-ID | <8c1eef8c-2ba4-441e-aa86-36486b56a261@n12g2000yqb.googlegroups.com> |
I have read that size_t can hold an unsigned int. I have been playing
with using size_t as a return value and I am not sure I should. I
wrote the following code to demonstrate the issue:
#include <stdio.h>
#include <stdlib.h>
static size_t test(size_t test2) {
size_t a;
a = test2;
return a;
}
int main(int argc, char **argv) {
size_t b,c;
b = -1;
c = test(b);
if (c == -1)
printf("here\n");
else
printf("there\n");
printf("c = %zu\n",c);
return 0;
}
When b is -1 I see:
here
c = 18446744073709551615
When b is 3 I see:
there
c = 3
While I realize using an unsigned int to store a negative number is
not proper, why does it sort of work? By sort of work I mean the
comparison works but the printf doesn't. However if I change the
printf("c = %zu\n",c); to printf("c = %d\n",c) then when b is -1 I see
here and c = -1.
So should I use a size_t to hold -1? If not why does the comparison
work? I am using Ubuntu Lucid.
Thanks,
[toc] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2012-02-11 15:00 -0500 |
| Message-ID | <jh6h8c$74f$1@dont-email.me> |
| In reply to | #17117 |
On 2/11/2012 14:21, Robert Hayes wrote:
> I have read that size_t can hold an unsigned int. I have been playing
> with using size_t as a return value and I am not sure I should. I
> wrote the following code to demonstrate the issue:
>
> #include<stdio.h>
> #include<stdlib.h>
>
> static size_t test(size_t test2) {
> size_t a;
> a = test2;
> return a;
> }
>
> int main(int argc, char **argv) {
> size_t b,c;
> b = -1;
> c = test(b);
> if (c == -1)
> printf("here\n");
> else
> printf("there\n");
>
> printf("c = %zu\n",c);
> return 0;
> }
>
> When b is -1 I see:
> here
> c = 18446744073709551615
>
> When b is 3 I see:
> there
> c = 3
>
> While I realize using an unsigned int to store a negative number is
> not proper, why does it sort of work? By sort of work I mean the
> comparison works but the printf doesn't. However if I change the
> printf("c = %zu\n",c); to printf("c = %d\n",c) then when b is -1 I see
> here and c = -1.
>
> So should I use a size_t to hold -1? If not why does the comparison
> work? I am using Ubuntu Lucid.
When the value '-1' is converted to a 'size_t' on your platform, it'll
yield the value '18446744073709551615', which is the maximum value
representable with 64 value bits.
In your comparison before "here," the '-1' is promoted to a 'size_t'
value for the comparison. So your comparison is actually:
if (c == 18446744073709551615)
printf("here\n");
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-02-11 23:24 +0000 |
| Message-ID | <0.debd3f7becfe4b7286a8.20120211232435GMT.87ipjd9cng.fsf@bsb.me.uk> |
| In reply to | #17118 |
Shao Miller <sha0.miller@gmail.com> writes:
> On 2/11/2012 14:21, Robert Hayes wrote:
<snip>
>> size_t b,c;
<snip>
>> if (c == -1)
>> printf("here\n");
<snip>
> In your comparison before "here," the '-1' is promoted to a 'size_t'
> value for the comparison.
Just a niggle: it's not technically a promotion. The integer promotions
preserve value including sign. What's happening here is the "usual
arithmetic conversions" where a signed int is converted to an unsigned
integer type.
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Jeffrey R <joeff@nospam.com> |
|---|---|
| Date | 2012-02-11 19:58 +0000 |
| Message-ID | <jh6h9c$lh9$1@speranza.aioe.org> |
| In reply to | #17117 |
On Sat, 11 Feb 2012 11:21:23 -0800, Robert Hayes wrote:
> I have read that size_t can hold an unsigned int. I have been playing
> with using size_t as a return value and I am not sure I should. I wrote
> the following code to demonstrate the issue:
>
> #include <stdio.h>
> #include <stdlib.h>
>
> static size_t test(size_t test2) {
> size_t a;
> a = test2;
> return a;
> }
>
> int main(int argc, char **argv) {
> size_t b,c;
> b = -1;
> c = test(b);
> if (c == -1)
> printf("here\n");
> else
> printf("there\n");
>
> printf("c = %zu\n",c);
> return 0;
> }
>
> When b is -1 I see:
> here
> c = 18446744073709551615
>
> When b is 3 I see:
> there
> c = 3
>
> While I realize using an unsigned int to store a negative number is not
> proper, why does it sort of work? By sort of work I mean the comparison
> works but the printf doesn't. However if I change the printf("c =
> %zu\n",c); to printf("c = %d\n",c) then when b is -1 I see here and c =
> -1.
>
> So should I use a size_t to hold -1? If not why does the comparison
> work? I am using Ubuntu Lucid.
>
> Thanks,
Assigning -1 into a size_t is an Undefined Behavior. Anything can happen,
be glad it didn't trash your hard disk!
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2012-02-11 15:11 -0500 |
| Message-ID | <jh6i1f$c0k$1@dont-email.me> |
| In reply to | #17120 |
On 2/11/2012 2:58 PM, Jeffrey R wrote:
>
> Assigning -1 into a size_t is an Undefined Behavior. Anything can happen,
> be glad it didn't trash your hard disk!
Nonsense. The behavior is implementation-defined, not undefined.
(The implementation-defined aspect is the maximum value of the size_t
type; it can be as small as 65535 or as large as, as, well, as large
as Very Large Indeed.)
The conversion will not trash a disk, nor cause butterscotch
pudding to ooze from your keyboard, nor make demons fly out of your
nose. It will yield the largest value a size_t can hold, period.
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2012-02-11 15:07 -0500 |
| Message-ID | <jh6hr1$alf$1@dont-email.me> |
| In reply to | #17117 |
On 2/11/2012 2:21 PM, Robert Hayes wrote:
> I have read that size_t can hold an unsigned int. I have been playing
> with using size_t as a return value and I am not sure I should. I
> wrote the following code to demonstrate the issue:
>
> #include<stdio.h>
> #include<stdlib.h>
>
> static size_t test(size_t test2) {
> size_t a;
> a = test2;
> return a;
> }
>
> int main(int argc, char **argv) {
> size_t b,c;
> b = -1;
As you note, `b' is an unsigned integer. Arithmetic on unsigned
integer is modular ("clock arithmetic"), so adding 1 to the type's
maximum value wraps around to zero. Also, subtracting 1 from the
types minimum value (zero) wraps around to the maximum value. And
that's what happens here: Converting -1 to an unsigned type produces
the type's maximum value. In your case, it appears that size_t is
a 64-bit unsigned type, so -1 becomes 0xFFFFFFFFFFFFFFFF, the very
large value you've printed in decimal form.
> c = test(b);
> if (c == -1)
This compares the size_t value `c' to the (signed) int value -1.
When you compare dissimilar types, C converts the values to a common
type and compares the converted values. There's a bunch of rules about
what converts to what in which circumstances; in this case, the int
value is converted to size_t and compared with `c'. Converting -1
to size_t works here just as it did above, and yields that very large
number -- which is, of course, equal to the very large number in `c'.
> printf("here\n");
> else
> printf("there\n");
>
> printf("c = %zu\n",c);
> return 0;
> }
>
> When b is -1 I see:
> here
> c = 18446744073709551615
>
> When b is 3 I see:
> there
> c = 3
>
> While I realize using an unsigned int to store a negative number is
> not proper, why does it sort of work? By sort of work I mean the
> comparison works but the printf doesn't.
Once you take the conversions into account, I think you'll agree
that both constructs "work."
> However if I change the
> printf("c = %zu\n",c); to printf("c = %d\n",c) then when b is -1 I see
> here and c = -1.
Happenstance. The "%d" conversion specifier must match a (signed)
int argument, but you're feeding it a size_t. Since the argument is
not of the expected type, you get the dreaded Undefined Behavior: C no
longer guarantees anything about what your program will do. (By the
way, gcc will warn you about mismatches of this kind if you crank up
its warning levels a bit: "-Wall -W -std=c99" is a reasonable start,
and you can get it to be even more picky if you wish.)
What (probably) happened is that "%d" looked at (probably) one
half or the other of the 64-bit size_t value, saw that the half had
all bits set, and interpreted that as the int value minus one. What
happened to the other half remains shrouded in mystery: Maybe it
just sat in a CPU register and was ignored, maybe it hung around in
a stack slot ready to confuse the next conversion, maybe it donated
your bank balance to the Greek bailout fund.
> So should I use a size_t to hold -1? If not why does the comparison
> work? I am using Ubuntu Lucid.
size_t cannot hold -1, nor any other negative value. It can,
however, hold the "wrapped around" value that results from converting
-1 to size_t; this value is large and positive. You can, if you
like, impute some special meaning to that large value, just as you
might treat zero as special, or -42 (in a signed type). Just don't
expect `(size_t)-1' to be negative, because it ain't.
size_t is also unable to hold extremely large positive values:
There is a maximum possible value for a size_t. If you try to go
above the maximum, the too-large number wraps around and becomes a
small non-negative value.
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | Robert Hayes <rhyes80@gmail.com> |
|---|---|
| Date | 2012-02-11 12:42 -0800 |
| Message-ID | <65729073-738d-4faf-9cbd-20e020532949@p7g2000yqk.googlegroups.com> |
| In reply to | #17122 |
On Feb 11, 2:07 pm, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
> On 2/11/2012 2:21 PM, Robert wrote:
> > I have read that size_t can hold an unsigned int. I have been playing
> > with using size_t as a return value and I am not sure I should. I
> > wrote the following code to demonstrate the issue:
>
> > #include<stdio.h>
> > #include<stdlib.h>
>
> > static size_t test(size_t test2) {
> > size_t a;
> > a = test2;
> > return a;
> > }
>
> > int main(int argc, char **argv) {
> > size_t b,c;
> > b = -1;
>
> As you note, `b' is an unsigned integer. Arithmetic on unsigned
> integer is modular ("clock arithmetic"), so adding 1 to the type's
> maximum value wraps around to zero. Also, subtracting 1 from the
> types minimum value (zero) wraps around to the maximum value. And
> that's what happens here: Converting -1 to an unsigned type produces
> the type's maximum value. In your case, it appears that size_t is
> a 64-bit unsigned type, so -1 becomes 0xFFFFFFFFFFFFFFFF, the very
> large value you've printed in decimal form.
>
> > c = test(b);
> > if (c == -1)
>
> This compares the size_t value `c' to the (signed) int value -1.
> When you compare dissimilar types, C converts the values to a common
> type and compares the converted values. There's a bunch of rules about
> what converts to what in which circumstances; in this case, the int
> value is converted to size_t and compared with `c'. Converting -1
> to size_t works here just as it did above, and yields that very large
> number -- which is, of course, equal to the very large number in `c'.
> > printf("here\n");
> > else
> > printf("there\n");
>
> > printf("c = %zu\n",c);
> > return 0;
> > }
>
> > When b is -1 I see:
> > here
> > c = 18446744073709551615
>
> > When b is 3 I see:
> > there
> > c = 3
>
> > While I realize using an unsigned int to store a negative number is
> > not proper, why does it sort of work? By sort of work I mean the
> > comparison works but the printf doesn't.
>
> Once you take the conversions into account, I think you'll agree
> that both constructs "work."
>
> > However if I change the
> > printf("c = %zu\n",c); to printf("c = %d\n",c) then when b is -1 I see
> > here and c = -1.
>
> Happenstance. The "%d" conversion specifier must match a (signed)
> int argument, but you're feeding it a size_t. Since the argument is
> not of the expected type, you get the dreaded Undefined Behavior: C no
> longer guarantees anything about what your program will do. (By the
> way, gcc will warn you about mismatches of this kind if you crank up
> its warning levels a bit: "-Wall -W -std=c99" is a reasonable start,
> and you can get it to be even more picky if you wish.)
>
> What (probably) happened is that "%d" looked at (probably) one
> half or the other of the 64-bit size_t value, saw that the half had
> all bits set, and interpreted that as the int value minus one. What
> happened to the other half remains shrouded in mystery: Maybe it
> just sat in a CPU register and was ignored, maybe it hung around in
> a stack slot ready to confuse the next conversion, maybe it donated
> your bank balance to the Greek bailout fund.
>
> > So should I use a size_t to hold -1? If not why does the comparison
> > work? I am using Ubuntu Lucid.
>
> size_t cannot hold -1, nor any other negative value. It can,
> however, hold the "wrapped around" value that results from converting
> -1 to size_t; this value is large and positive. You can, if you
> like, impute some special meaning to that large value, just as you
> might treat zero as special, or -42 (in a signed type). Just don't
> expect `(size_t)-1' to be negative, because it ain't.
>
> size_t is also unable to hold extremely large positive values:
> There is a maximum possible value for a size_t. If you try to go
> above the maximum, the too-large number wraps around and becomes a
> small non-negative value.
>
> --
> Eric Sosman
> esos...@ieee-dot-org.invalid
Thank you for the clear explanation. I will not use a size_t to hold
a negative number.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2012-02-11 13:19 -0800 |
| Message-ID | <89d81138-2680-4945-825d-ed7ce7d5e584@t2g2000yqk.googlegroups.com> |
| In reply to | #17127 |
On Feb 11, 8:42 pm, Robert Hayes <rhye...@gmail.com> wrote: > > Thank you for the clear explanation. I will not use a size_t to hold > a negative number.- Hide quoted text - > There's an example of a size_t holding a negative number on the thread about stripping right spaces. -- Vist my website. MPI tutorial http://www.malcolm.mclean.site11.com/www
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-02-11 17:10 -0800 |
| Message-ID | <lnvcnckgb0.fsf@nuthaus.mib.org> |
| In reply to | #17132 |
Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
> On Feb 11, 8:42 pm, Robert Hayes <rhye...@gmail.com> wrote:
>>
>> Thank you for the clear explanation. I will not use a size_t to hold
>> a negative number.- Hide quoted text -
>>
> There's an example of a size_t holding a negative number on the thread
> about stripping right spaces.
No, there isn't.
I don't recall the details from that thread. The point is that size_t
simply cannot hold a negative number.
You can convert a negative number (of a signed type) to size_t, and
store the result of the conversion in a size_t object. You *probably*
can then convert the stored value back to the signed type, but the
result is implementation-defined.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2012-02-12 03:48 -0800 |
| Message-ID | <45f16428-5700-4be1-90b0-b925af5a69ed@f14g2000yqe.googlegroups.com> |
| In reply to | #17161 |
On Feb 12, 1:10 am, Keith Thompson <ks...@mib.org> wrote:
> Malcolm McLean <malcolm.mcle...@btinternet.com> writes:
> > On Feb 11, 8:42 pm, Robert Hayes <rhye...@gmail.com> wrote:
>
> >> Thank you for the clear explanation. I will not use a size_t to hold
> >> a negative number.- Hide quoted text -
>
> > There's an example of a size_t holding a negative number on the thread
> > about stripping right spaces.
>
> No, there isn't.
>
> I don't recall the details from that thread. The point is that size_t
> simply cannot hold a negative number.
>
Here it is
[ from Ben ]
size_t i = strlen(s);
while (i-- > 0 && isspace(s[i]))
/* do nothing */;
s[i + 1] = '\0';
If the string is all spaces, or empty, I'd say that i goes to -1.
--
Malcolm's website
http://www.malcolmmclean.site11.com/www
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-02-12 04:04 -0800 |
| Message-ID | <lnmx8ojm1b.fsf@nuthaus.mib.org> |
| In reply to | #17170 |
Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
> On Feb 12, 1:10 am, Keith Thompson <ks...@mib.org> wrote:
>> Malcolm McLean <malcolm.mcle...@btinternet.com> writes:
>> > On Feb 11, 8:42 pm, Robert Hayes <rhye...@gmail.com> wrote:
>>
>> >> Thank you for the clear explanation. I will not use a size_t to hold
>> >> a negative number.- Hide quoted text -
>>
>> > There's an example of a size_t holding a negative number on the thread
>> > about stripping right spaces.
>>
>> No, there isn't.
>>
>> I don't recall the details from that thread. The point is that size_t
>> simply cannot hold a negative number.
>
> Here it is
> [ from Ben ]
> size_t i = strlen(s);
> while (i-- > 0 && isspace(s[i]))
> /* do nothing */;
> s[i + 1] = '\0';
>
> If the string is all spaces, or empty, I'd say that i goes to -1.
No, it goes to SIZE_MAX; it cannot represent the value -1.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Jeffrey R <joeff@nospam.com> |
|---|---|
| Date | 2012-02-11 22:25 +0000 |
| Message-ID | <jh6ps6$8st$1@speranza.aioe.org> |
| In reply to | #17127 |
On Sat, 11 Feb 2012 12:42:30 -0800, Robert Hayes wrote:
> On Feb 11, 2:07 pm, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
>> On 2/11/2012 2:21 PM, Robert wrote:
>> > I have read that size_t can hold an unsigned int. I have been
>> > playing with using size_t as a return value and I am not sure I
>> > should. I wrote the following code to demonstrate the issue:
>>
>> > #include<stdio.h>
>> > #include<stdlib.h>
>>
>> > static size_t test(size_t test2) {
>> > size_t a;
>> > a = test2;
>> > return a;
>> > }
>>
>> > int main(int argc, char **argv) {
>> > size_t b,c;
>> > b = -1;
>>
>> As you note, `b' is an unsigned integer. Arithmetic on
>> unsigned
>> integer is modular ("clock arithmetic"), so adding 1 to the type's
>> maximum value wraps around to zero. Also, subtracting 1 from the types
>> minimum value (zero) wraps around to the maximum value. And that's
>> what happens here: Converting -1 to an unsigned type produces the
>> type's maximum value. In your case, it appears that size_t is a 64-bit
>> unsigned type, so -1 becomes 0xFFFFFFFFFFFFFFFF, the very large value
>> you've printed in decimal form.
>>
>> > c = test(b);
>> > if (c == -1)
>>
>> This compares the size_t value `c' to the (signed) int value
>> -1.
>> When you compare dissimilar types, C converts the values to a common
>> type and compares the converted values. There's a bunch of rules about
>> what converts to what in which circumstances; in this case, the int
>> value is converted to size_t and compared with `c'. Converting -1 to
>> size_t works here just as it did above, and yields that very large
>> number -- which is, of course, equal to the very large number in `c'.
>> > printf("here\n");
>> > else
>> > printf("there\n");
>>
>> > printf("c = %zu\n",c);
>> > return 0;
>> > }
>>
>> > When b is -1 I see:
>> > here
>> > c = 18446744073709551615
>>
>> > When b is 3 I see:
>> > there
>> > c = 3
>>
>> > While I realize using an unsigned int to store a negative number is
>> > not proper, why does it sort of work? By sort of work I mean the
>> > comparison works but the printf doesn't.
>>
>> Once you take the conversions into account, I think you'll
>> agree
>> that both constructs "work."
>>
>> > However if I change the
>> > printf("c = %zu\n",c); to printf("c = %d\n",c) then when b is -1 I
>> > see here and c = -1.
>>
>> Happenstance. The "%d" conversion specifier must match a
>> (signed)
>> int argument, but you're feeding it a size_t. Since the argument is
>> not of the expected type, you get the dreaded Undefined Behavior: C no
>> longer guarantees anything about what your program will do. (By the
>> way, gcc will warn you about mismatches of this kind if you crank up
>> its warning levels a bit: "-Wall -W -std=c99" is a reasonable start,
>> and you can get it to be even more picky if you wish.)
>>
>> What (probably) happened is that "%d" looked at (probably) one
>> half or the other of the 64-bit size_t value, saw that the half had all
>> bits set, and interpreted that as the int value minus one. What
>> happened to the other half remains shrouded in mystery: Maybe it just
>> sat in a CPU register and was ignored, maybe it hung around in a stack
>> slot ready to confuse the next conversion, maybe it donated your bank
>> balance to the Greek bailout fund.
>>
>> > So should I use a size_t to hold -1? If not why does the comparison
>> > work? I am using Ubuntu Lucid.
>>
>> size_t cannot hold -1, nor any other negative value. It can,
>> however, hold the "wrapped around" value that results from converting
>> -1 to size_t; this value is large and positive. You can, if you like,
>> impute some special meaning to that large value, just as you might
>> treat zero as special, or -42 (in a signed type). Just don't expect
>> `(size_t)-1' to be negative, because it ain't.
>>
>> size_t is also unable to hold extremely large positive values:
>> There is a maximum possible value for a size_t. If you try to go above
>> the maximum, the too-large number wraps around and becomes a small
>> non-negative value.
>>
>> --
>> Eric Sosman
>> esos...@ieee-dot-org.invalid
>
>
> Thank you for the clear explanation. I will not use a size_t to hold a
> negative number.
This explanation may seem clear but it is also WRONG!
It is assuming that the CPU is 2-s compliment.
In many common cases eg on x86, behavior will be as Eric Sossman
describes. However, this is not guaranteed and not portable. On other
platforms it could trigger an overflow signal from the ALU or lead to a
Trap Representation. In fact, Undefined Behavior means that anything
could happen! Including (in theory) reformatting your hard disk.
A size_t is an UN-SIGNED type, trying to store a negative number in it is
a programmer error generating an undefined behavior.
[toc] | [prev] | [next] | [standalone]
| From | Devil with the China Blue Dress <chine.bleu@yahoo.com> |
|---|---|
| Date | 2012-02-11 14:36 -0800 |
| Message-ID | <chine.bleu-B38784.14362111022012@news.eternal-september.org> |
| In reply to | #17140 |
In article <jh6ps6$8st$1@speranza.aioe.org>, Jeffrey R <joeff@nospam.com> wrote: > It is assuming that the CPU is 2-s compliment. There is nothing quite as wonderful as a ones complement machine where -0==0 and -0<0. -- My name Indigo Montoya. | It's Coraline, not Caroline. You flamed my father. | I'm whoever you want me to be. Prepare to be spanked. | Annoying Usenet one post at a time. Stop posting that! | At least I can stay in character.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-02-11 23:17 +0000 |
| Message-ID | <0.59ce29272d6a5eaec568.20120211231703GMT.87obt59d00.fsf@bsb.me.uk> |
| In reply to | #17144 |
Devil with the China Blue Dress <chine.bleu@yahoo.com> writes: > In article <jh6ps6$8st$1@speranza.aioe.org>, Jeffrey R <joeff@nospam.com> > wrote: > >> It is assuming that the CPU is 2-s compliment. > > There is nothing quite as wonderful as a ones complement machine where > -0==0 and -0<0. A C implementation would, I think, have to hide that from the programmer. In C, the value of a negative zero is zero and will therefore not compare less than zero. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Jeroen Mostert <jmostert@xs4all.nl> |
|---|---|
| Date | 2012-02-11 23:46 +0100 |
| Message-ID | <4f36efde$0$6935$e4fe514c@news2.news.xs4all.nl> |
| In reply to | #17140 |
On 2012-02-11 23:25, Jeffrey R wrote: > A size_t is an UN-SIGNED type, trying to store a negative number in it is > a programmer error generating an undefined behavior. (size_t) -1 is well-defined on any C implementation, per section 6.3.1.3p2 of the standard. It's equal to the maximum value a size_t can hold. This does not depend on the underlying representation. There are operations on signed values that invoke undefined behavior (in fact, integer overflow is the poster child for undefined behavior), but converting signed values to unsigned values isn't one of them. -- J.
[toc] | [prev] | [next] | [standalone]
| From | pete <pfiland@mindspring.com> |
|---|---|
| Date | 2012-02-11 19:18 -0500 |
| Message-ID | <4F370555.7387@mindspring.com> |
| In reply to | #17148 |
Jeroen Mostert wrote:
>
> On 2012-02-11 23:25, Jeffrey R wrote:
> > A size_t is an UN-SIGNED type,
> > trying to store a negative number in it is
> > a programmer error generating an undefined behavior.
>
> (size_t) -1 is well-defined on any C implementation,
> per section 6.3.1.3p2
> of the standard.
> It's equal to the maximum value a size_t can hold. This
> does not depend on the underlying representation.
I'll post the text,
just in case Jeffrey R thinks that you're making this up.
6.3.1.3 Signed and unsigned integers
1 When a value with integer type is converted
to another integer type other than _Bool,
if the value can be represented by the new type,
it is unchanged.
2 Otherwise, if the new type is unsigned,
the value is converted by repeatedly adding
or subtracting one more than the maximum value
that can be represented in the new type
until the value is in the range of the new type.60)
60) The rules describe arithmetic on the mathematical value,
not the value of a given type of expression.
--
pete
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2012-02-12 08:38 -0500 |
| Message-ID | <jh8fdi$af9$1@dont-email.me> |
| In reply to | #17140 |
On 2/11/2012 5:25 PM, Jeffrey R wrote:
> On Sat, 11 Feb 2012 12:42:30 -0800, Robert Hayes wrote:
>
>> On Feb 11, 2:07 pm, Eric Sosman<esos...@ieee-dot-org.invalid> wrote:
>>> [...]
>> Thank you for the clear explanation. I will not use a size_t to hold a
>> negative number.
>
> This explanation may seem clear but it is also WRONG!
Although I see no flaws, it's possible I've overlooked something.
I'll admit to a certain breeziness and glossing over of niggling
detail in the interest of clarity, but I feel that's acceptable and
that any such hand-waving is far from WRONG.
> It is assuming that the CPU is 2-s compliment.
No, nor does it assume two's complEment.
> In many common cases eg on x86, behavior will be as Eric Sossman
> describes.
Correct (except that your S key sticks). "Many common cases"
is a subset of "all cases," so a condition that holds for the latter
also holds for the former.
> However, this is not guaranteed and not portable.
True: The behavior is not portable to a system lacking C.
> On other
> platforms it could trigger an overflow signal from the ALU or lead to a
> Trap Representation. In fact, Undefined Behavior means that anything
> could happen! Including (in theory) reformatting your hard disk.
Only if the platform runs C code on a non-C implementation. If
it uses a C implementation there is an implementation-defined aspect
to the conversion (the maximum size_t value is implemenation-dependent),
but there is no undefined behavior, no trap representation, and no
reformatting of your disk, whatever its hardness.
> A size_t is an UN-SIGNED type, trying to store a negative number in it is
> a programmer error generating an undefined behavior.
Alas, you are WRONG. A few references for remedial review:
6.2.5p9: "[...] A computation involving unsigned operands can
never overflow, because a result that cannot be represented by
the resulting unsigned integer type is reduced modulo the
number that is one greater than the largest value that can
be represented by the resulting type."
6.2.6.2p1, footnote 53: "[...] no arithmetic operation on
valid values can generate a trap representation other than
as part of an exceptional condition such as an overflow, and
this cannot occur with unsigned types."
6.3.1.3p2: "[converting out-of-range integers ...] if the
new type is unsigned, the value is converted by repeatedly
adding or subtracting one more than the maximum value that
can be represented in the new type until the value is in the
range of the new type."
If you believe these three citations are WRONG, I encourage you
to file a defect report with ISO.
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-02-11 23:32 +0000 |
| Message-ID | <0.41b4a82c70b7dcfabf6f.20120211233256GMT.87d39l9c9j.fsf@bsb.me.uk> |
| In reply to | #17127 |
Robert Hayes <rhyes80@gmail.com> writes: > On Feb 11, 2:07 pm, Eric Sosman <esos...@ieee-dot-org.invalid> wrote: <snip> >> size_t cannot hold -1, nor any other negative value. It can, >> however, hold the "wrapped around" value that results from converting >> -1 to size_t; this value is large and positive. You can, if you >> like, impute some special meaning to that large value, just as you >> might treat zero as special, or -42 (in a signed type). Just don't >> expect `(size_t)-1' to be negative, because it ain't. <snip> > Thank you for the clear explanation. I will not use a size_t to hold > a negative number. Don't worry you can't! But I think I get what you mean. However, I don't think that's the take away message here. It's not uncommon to use (size_t)-1 as a special signifier. Sometimes size_t is the natural return type and yet you want to use an in-band error indicator. (size_t)-1 is good for the job. In fact, C defines several standard functions that do this. A couple of them even signal two different errors using (size_t)-1 and (size_t)-2. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | pete <pfiland@mindspring.com> |
|---|---|
| Date | 2012-02-11 19:15 -0500 |
| Message-ID | <4F37049C.2FEC@mindspring.com> |
| In reply to | #17127 |
Robert Hayes wrote: > > On Feb 11, 2:07 pm, Eric Sosman <esos...@ieee-dot-org.invalid> wrote: > > On 2/11/2012 2:21 PM, Robert wrote: > > > I have read that size_t can hold an unsigned int. > > > I have been playing > > > with using size_t as a return value and I am not sure I should. > Thank you for the clear explanation. I will not use a size_t to hold > a negative number. I *would* use ((size_t)-1) as a return value to indicate an extraordinary condition, *if* there was no possibility that that value might be returned otherwise. The index of the last element of an array with ((size_t)-1) elements, is ((size_t)-2). So, if a function was supposed to return the index number of an array element, a return value of ((size_t)-1) could be used to indicate a problem. -- pete
[toc] | [prev] | [next] | [standalone]
| From | Ralph Spitzner <rasp@spitzner.org> |
|---|---|
| Date | 2012-02-13 13:51 +0100 |
| Message-ID | <pjdn09-6om.ln1@spitzner.org> |
| In reply to | #17122 |
Eric Sosman wrote:
[...]
> all bits set, and interpreted that as the int value minus one. What
> happened to the other half remains shrouded in mystery: Maybe it
> just sat in a CPU register and was ignored, maybe it hung around in
> a stack slot ready to confuse the next conversion, maybe it donated
> your bank balance to the Greek bailout fund.
Can you rephrase/downsize that statement, so we all could use it
as a signature ?
:-P
-rasp
--
RTMPDump & ffmpeg are your friends..
-icke
[toc] | [prev] | [next] | [standalone]
Page 1 of 3 [1] 2 3 Next page →
Back to top | Article view | comp.lang.c
csiph-web