return -1 using size_t???

Discussion in 'C Programming' started by Robert Hayes, Feb 11, 2012.

  1. Robert Hayes

    Robert Hayes Guest

    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,
     
    Robert Hayes, Feb 11, 2012
    #1
    1. Advertising

  2. Robert Hayes

    Jeffrey R Guest

    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!
     
    Jeffrey R, Feb 11, 2012
    #2
    1. Advertising

  3. Robert Hayes

    Shao Miller Guest

    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");
     
    Shao Miller, Feb 11, 2012
    #3
  4. Robert Hayes

    Eric Sosman Guest

    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
    d
     
    Eric Sosman, Feb 11, 2012
    #4
  5. Robert Hayes

    Eric Sosman Guest

    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
    d
     
    Eric Sosman, Feb 11, 2012
    #5
  6. Robert Hayes

    Robert Hayes Guest

    On Feb 11, 2:07 pm, Eric Sosman <> 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
    >



    Thank you for the clear explanation. I will not use a size_t to hold
    a negative number.
     
    Robert Hayes, Feb 11, 2012
    #6
  7. On Feb 11, 8:42 pm, Robert Hayes <> 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
     
    Malcolm McLean, Feb 11, 2012
    #7
  8. Robert Hayes

    Eric Sosman Guest

    On 2/11/2012 3:40 PM, Devil with the China Blue Dress wrote:
    > In article<>,
    > Robert Hayes<> wrote:
    >
    >> 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

    >
    > On a twos complement CPU, [...]


    On no C implementation anywhere does size_t use two's complement.
    Nor ones' complement, nor signed magnitude.

    > Addition and subtraction will yield the same bit patterns with either
    > interpretation. If the most significant bits are equal, comparison will be the
    > same.


    C's comparison and equality operators use values, not bit patterns.
    Here's (slightly non-portable) proof:

    #include <string.h>
    #include <math.h>
    #include <assert.h>
    ...
    float f = NAN;
    float g = NAN;
    assert(memcmp(&f, &g, sizeof f) == 0); // identical bits
    assert(f != g); // unequal values

    Here's another proof (I think this one's portable):

    struct {
    unsigned int p : 1;
    unsigned int q : 15;
    } s;
    s.p = 1;
    s.q = 1;
    assert(s.p == s.q); // different bits, equal values

    --
    Eric Sosman
    d
     
    Eric Sosman, Feb 11, 2012
    #8
  9. Robert Hayes

    Eric Sosman Guest

    On 2/11/2012 5:11 PM, Devil with the China Blue Dress wrote:
    > In article<jh6oh8$i77$>,
    > Eric Sosman<> wrote:
    >
    >> On 2/11/2012 3:40 PM, Devil with the China Blue Dress wrote:
    >>> In
    >>> article<>,
    >>> Robert Hayes<> wrote:
    >>>
    >>>> 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
    >>>
    >>> On a twos complement CPU, [...]

    >
    > And you snipped that all references were to integers


    The question was about *unsigned* integers. *Unsigned* integers
    in C never use complement represention.

    >> Here's another proof (I think this one's portable):
    >>
    >> struct {
    >> unsigned int p : 1;
    >> unsigned int q : 15;
    >> } s;
    >> s.p = 1;
    >> s.q = 1;
    >> assert(s.p == s.q); // different bits, equal values

    >
    > The bit pattern of s.p would be 0...1 and s.q would be 0...000000000000001
    > widenned to the number of bits in an unsigned int.


    The bit pattern of s.p is `1', period. The bit pattern of
    s.q is `000000000000001', period. These bit patterns necessarily
    disagree, since they're not even the same size.

    I've made two points about your post: First, talking about
    representation schemes for negative numbers is silly when the
    type in question is unsigned. Second, suggesting that comparison
    relies on bit patterns without regard to types is not merely
    silly, but wrong. (I could also have taken issue with the
    misstatement about "most significant bits," but enough's enough.)

    --
    Eric Sosman
    d
     
    Eric Sosman, Feb 11, 2012
    #9
  10. Robert Hayes

    Jeffrey R Guest

    On Sat, 11 Feb 2012 12:42:30 -0800, Robert Hayes wrote:

    > On Feb 11, 2:07 pm, Eric Sosman <> 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
    >>

    >
    >
    > 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.
     
    Jeffrey R, Feb 11, 2012
    #10
  11. On Sat, 11 Feb 2012 11:21:23 -0800 (PST), Robert Hayes
    <> wrote:

    >I have read that size_t can hold an unsigned int. I have been playing


    size_t is defined as an unsigned integer type but it need not be
    unsigned int. I expect on most systems it is unsigned long as
    recommended in 7.17-4 of n1256.

    --
    Remove del for email
     
    Barry Schwarz, Feb 11, 2012
    #11
  12. 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.
     
    Jeroen Mostert, Feb 11, 2012
    #12
  13. Robert Hayes

    Willem Guest

    Devil with the China Blue Dress wrote:
    ) No, the question was about casting an signed number (-1) to an unsigned type.
    ) That this can be done and is closed under addition is a property of twos
    ) complement integers.

    No, that this can be done is a result of the wording of the C standard.
    Case in point: it also works on ones complement machines.
    Twos complement is just a red herring in this case.


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
     
    Willem, Feb 11, 2012
    #13
  14. Devil with the China Blue Dress <> writes:

    > In article <jh6ps6$8st$>, Jeffrey R <>
    > 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.
     
    Ben Bacarisse, Feb 11, 2012
    #14
  15. Robert Hayes

    Jens Gustedt Guest

    Am 02/11/2012 11:31 PM, schrieb Devil with the China Blue Dress:
    > No, the question was about casting an signed number (-1) to an unsigned type.
    > That this can be done and is closed under addition is a property of twos
    > complement integers.


    No, the representation of the -1 has nothing do with the result of
    converting it into any unsigned integer type. As has been already been
    repeated several times upthread, C strictly defines what has to be done
    when converting a negative *value* to an unsigned integer type. And in
    particular it uses the value and not the representation.

    For all conforming C implementations the result of converting -1 to
    size_t is SIZE_MAX.

    Jens
     
    Jens Gustedt, Feb 11, 2012
    #15
  16. Shao Miller <> 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.
     
    Ben Bacarisse, Feb 11, 2012
    #16
  17. Robert Hayes <> writes:

    > On Feb 11, 2:07 pm, Eric Sosman <> 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.
     
    Ben Bacarisse, Feb 11, 2012
    #17
  18. Malcolm McLean <> writes:
    > On Feb 11, 8:42 pm, Robert Hayes <> 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) <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"
     
    Keith Thompson, Feb 12, 2012
    #18
  19. Barry Schwarz <> writes:
    > On Sat, 11 Feb 2012 11:21:23 -0800 (PST), Robert Hayes
    > <> wrote:
    >>I have read that size_t can hold an unsigned int. I have been playing

    >
    > size_t is defined as an unsigned integer type but it need not be
    > unsigned int. I expect on most systems it is unsigned long as
    > recommended in 7.17-4 of n1256.


    That paragraph doesn't recommend using unsigned long; it recommends
    *not* using a type with conversion rank greater than that of
    unsigned long unless it's necessary. An implementation defining
    size_t as either unsigned int or unsigned long would satisfy the
    recommendation.

    --
    Keith Thompson (The_Other_Keith) <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"
     
    Keith Thompson, Feb 12, 2012
    #19
  20. On Feb 12, 1:10 am, Keith Thompson <> wrote:
    > Malcolm McLean <> writes:
    > > On Feb 11, 8:42 pm, Robert Hayes <> 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))
    /* 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
     
    Malcolm McLean, Feb 12, 2012
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jakob Bieling

    Q: Using an extern const size_t?

    Jakob Bieling, Feb 28, 2004, in forum: C++
    Replies:
    5
    Views:
    565
    Jakob Bieling
    Feb 28, 2004
  2. Greenhorn
    Replies:
    15
    Views:
    852
    Keith Thompson
    Mar 6, 2005
  3. Alex Vinokur
    Replies:
    9
    Views:
    817
    James Kanze
    Oct 13, 2008
  4. Alex Vinokur
    Replies:
    1
    Views:
    595
  5. James Kanze
    Replies:
    3
    Views:
    956
    Öö Tiib
    Feb 21, 2011
Loading...

Share This Page