Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #17117 > unrolled thread

return -1 using size_t???

Started byRobert Hayes <rhyes80@gmail.com>
First post2012-02-11 11:21 -0800
Last post2012-02-11 17:34 -0800
Articles 20 on this page of 56 — 22 participants

Back to article view | Back to comp.lang.c


Contents

  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 →


#17117 — return -1 using size_t???

FromRobert Hayes <rhyes80@gmail.com>
Date2012-02-11 11:21 -0800
Subjectreturn -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]


#17118

FromShao Miller <sha0.miller@gmail.com>
Date2012-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]


#17154

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-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]


#17120

FromJeffrey R <joeff@nospam.com>
Date2012-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]


#17123

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-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]


#17122

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-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]


#17127

FromRobert Hayes <rhyes80@gmail.com>
Date2012-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]


#17132

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2012-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]


#17161

FromKeith Thompson <kst-u@mib.org>
Date2012-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]


#17170

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2012-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]


#17171

FromKeith Thompson <kst-u@mib.org>
Date2012-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]


#17140

FromJeffrey R <joeff@nospam.com>
Date2012-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]


#17144

FromDevil with the China Blue Dress <chine.bleu@yahoo.com>
Date2012-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]


#17152

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-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]


#17148

FromJeroen Mostert <jmostert@xs4all.nl>
Date2012-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]


#17160

Frompete <pfiland@mindspring.com>
Date2012-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]


#17173

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-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]


#17155

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-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]


#17159

Frompete <pfiland@mindspring.com>
Date2012-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]


#17214

FromRalph Spitzner <rasp@spitzner.org>
Date2012-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