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


Groups > comp.lang.c > #17140

Re: return -1 using size_t???

From Jeffrey R <joeff@nospam.com>
Newsgroups comp.lang.c
Subject Re: return -1 using size_t???
Date 2012-02-11 22:25 +0000
Organization Aioe.org NNTP Server
Message-ID <jh6ps6$8st$1@speranza.aioe.org> (permalink)
References <8c1eef8c-2ba4-441e-aa86-36486b56a261@n12g2000yqb.googlegroups.com> <jh6hr1$alf$1@dont-email.me> <65729073-738d-4faf-9cbd-20e020532949@p7g2000yqk.googlegroups.com>

Show all headers | View raw


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.

Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

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

csiph-web