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


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

What is the rank of size_t ?

Started bySpiros Bousbouras <spibou@gmail.com>
First post2020-05-27 12:49 +0000
Last post2020-06-02 10:06 +0200
Articles 20 on this page of 25 — 11 participants

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


Contents

  What is the rank of  size_t ? Spiros Bousbouras <spibou@gmail.com> - 2020-05-27 12:49 +0000
    Re: What is the rank of  size_t ? Spiros Bousbouras <spibou@gmail.com> - 2020-05-27 13:54 +0000
      Re: What is the rank of size_t ? James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-05-27 11:14 -0400
        Re: What is the rank of size_t ? Spiros Bousbouras <spibou@gmail.com> - 2020-05-27 19:03 +0000
          Re: What is the rank of size_t ? James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-05-27 18:09 -0400
      Re: What is the rank of  size_t ? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-05-30 01:54 -0700
    Re: What is the rank of size_t ? James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-05-27 09:59 -0400
      Re: What is the rank of size_t ? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-05-27 07:37 -0700
        Re: What is the rank of size_t ? James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-05-27 11:02 -0400
      Re: What is the rank of size_t ? Vir Campestris <vir.campestris@invalid.invalid> - 2020-05-27 20:46 +0100
        Re: What is the rank of size_t ? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-05-27 14:30 -0700
    Re: What is the rank of size_t ? Real Troll <real.troll@trolls.com> - 2020-05-28 06:35 -1000
      Re: What is the rank of size_t ? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-05-29 20:55 -0700
        Re: What is the rank of size_t ? Real Troll <Real.Troll@trolls.com> - 2020-05-30 08:05 -1000
          Re: What is the rank of size_t ? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-05-31 17:33 -0700
            Re: What is the rank of size_t ? Real Troll <real.troll@trolls.com> - 2020-06-01 01:45 -1000
              Re: What is the rank of size_t ? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-06-03 11:33 -0700
            Re: What is the rank of size_t ? Ike Naar <ike@otaku.sdf.org> - 2020-06-01 20:51 +0000
              Re: What is the rank of size_t ? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-06-03 11:16 -0700
      Re: What is the rank of size_t ? raltbos@xs4all.nl (Richard Bos) - 2020-05-31 09:12 +0000
        Re: What is the rank of size_t ? Real Troll <reasl.troll@trolls.com> - 2020-05-31 01:30 -1000
          Re: What is the rank of size_t ? raltbos@xs4all.nl (Richard Bos) - 2020-06-04 20:40 +0000
            Re: What is the rank of size_t ? Real Troll <real.troll@trolls.com> - 2020-06-04 12:50 -1000
    Re: What is the rank of  size_t ? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-05-30 00:55 -0700
    Re: What is the rank of size_t ? Bonita Montero <Bonita.Montero@gmail.com> - 2020-06-02 10:06 +0200

Page 1 of 2  [1] 2  Next page →


#152499 — What is the rank of size_t ?

FromSpiros Bousbouras <spibou@gmail.com>
Date2020-05-27 12:49 +0000
SubjectWhat is the rank of size_t ?
Message-ID<y88BWrDFndCB41zt@bongo-ra.co>
Specifically , if  a  has type  int  and  b  has type  size_t , can
a + b  overflow i.e. cause undefined behaviour ?

[toc] | [next] | [standalone]


#152500

FromSpiros Bousbouras <spibou@gmail.com>
Date2020-05-27 13:54 +0000
Message-ID<G4VDkHpajhgoQ0Hlk@bongo-ra.co>
In reply to#152499
On Wed, 27 May 2020 12:49:41 GMT
Spiros Bousbouras <spibou@gmail.com> wrote:
> Specifically , if  a  has type  int  and  b  has type  size_t , can
> a + b  overflow i.e. cause undefined behaviour ?

Let me expand on the question. First I will quote "6.3.1.8 Usual arithmetic
conversions" :

    Otherwise, the integer promotions are performed on both operands. Then
    the following rules are applied to the promoted operands:

      If both operands have the same type, then no further conversion is
      needed. Otherwise, if both operands have signed integer types or both
      have unsigned integer types, the operand with the type of lesser
      integer conversion rank is converted to the type of the operand with
      greater rank.

      Otherwise, if the operand that has unsigned integer type has rank
      greater or equal to the rank of the type of the other operand, then the
      operand with signed integer type is converted to the type of the
      operand with unsigned integer type.

      Otherwise, if the type of the operand with signed integer type can
      represent all of the values of the type of the operand with unsigned
      integer type, then the operand with unsigned integer type is converted
      to the type of the operand with signed integer type.

      Otherwise, both operands are converted to the unsigned integer type
      corresponding to the type of the operand with signed integer type.

The first 2 paragraphs don't apply because the standard doesn't say anything
about the rank of  size_t .The 3rd paragraph may apply and you can check
using the preprocessor as in

    #if SIZE_MAX >= INT_MAX
    .......
    #else
    .......
    #endif

taking advantage of the stipulation "For the purposes of this token
conversion and evaluation, all signed integer types and all unsigned integer
types act as if they have the same representation as, respectively, the types
intmax_t and uintmax_t defined in the header <stdint.h>." in "6.10.1
Conditional inclusion" .So in the above context the C interpretation of
SIZE_MAX >= INT_MAX    agrees with the mathematical interpretation.

But if the 3rd paragraph doesn't apply then for example in a situation  a+b
where  a  is  int  with value 1 and  b  is  size_t  with value  SIZE_MAX-2
then both will be converted to  unsigned int  and then the addition will be
performed. So it won't be undefined behaviour but the expression won't have
the mathematically correct result. Is my analysis correct ? If yes I find the
outcome counterintuitive. Note that if both had been converted to  size_t
then the expression would have the mathematically correct result.

Given the above , I think it would be more useful if the standard said
    The rank of  size_t  will be greater than the rank of any other unsigned
    integer type whose greatest value is less or equal than  SIZE_MAX .

In the scenarios I can think of , such a stipulation would make it easier for
programmers to reason about their code , would give more intuitive results
(according to my intuition anyway) and would give no additional burden to
implementations since likely they behave like this already.

All the above inspired a related question : are 2 distinct ranks always
comparable or is it possible to have ranks R1 and R2 where none of the
following applies :
    - R1 is smaller than R2
    - R2 is smaller than R1
    - R1 and R2 are equal

? I'm not sure if it's relevant to anything but it seems complicated to
examine all combinations of ranks and conversion rules to see if it might be
relevant so , unless there is a specific situation where it would be useful
to have ranks which are incomparable , it would be better if the standard
said that they are always comparable.

-- 
it's apparent that the source of the greatest direct duress experienced by
the ordinary adult is _not_ the state but rather the business that employs
him. Your foreman or supervisor gives you more or-else orders in a week than
the police do in a decade.
  theanarchistlibrary.org/library/bob-black-the-libertarian-as-conservative

[toc] | [prev] | [next] | [standalone]


#152505 — Re: What is the rank of size_t ?

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2020-05-27 11:14 -0400
SubjectRe: What is the rank of size_t ?
Message-ID<ram041$n9f$1@dont-email.me>
In reply to#152500
On 5/27/20 9:54 AM, Spiros Bousbouras wrote:
> On Wed, 27 May 2020 12:49:41 GMT
> Spiros Bousbouras <spibou@gmail.com> wrote:
>> Specifically , if  a  has type  int  and  b  has type  size_t , can
>> a + b  overflow i.e. cause undefined behaviour ?
> 
> Let me expand on the question. First I will quote "6.3.1.8 Usual arithmetic
> conversions" :
> 
>     Otherwise, the integer promotions are performed on both operands. Then
>     the following rules are applied to the promoted operands:
> 
>       If both operands have the same type, then no further conversion is
>       needed. Otherwise, if both operands have signed integer types or both
>       have unsigned integer types, the operand with the type of lesser
>       integer conversion rank is converted to the type of the operand with
>       greater rank.
> 
>       Otherwise, if the operand that has unsigned integer type has rank
>       greater or equal to the rank of the type of the other operand, then the
>       operand with signed integer type is converted to the type of the
>       operand with unsigned integer type.
> 
>       Otherwise, if the type of the operand with signed integer type can
>       represent all of the values of the type of the operand with unsigned
>       integer type, then the operand with unsigned integer type is converted
>       to the type of the operand with signed integer type.
> 
>       Otherwise, both operands are converted to the unsigned integer type
>       corresponding to the type of the operand with signed integer type.
> 
> The first 2 paragraphs don't apply because the standard doesn't say anything
> about the rank of  size_t .

Not quite. Since size_t is an unsigned integer type, and int is a signed
type, the first paragraph can apply only if size_t gets promoted to int,
in which case the two operands have the same type, and the rank of
size_t is irrelevant.

The standard does say something, indirectly, about the rank of size_t
that's relevant: it says that it's an unsigned integer type. It also
says "Every integer type has an integer conversion rank ..."
(6.3.1.1p1), and follows that with a set of rules that apply to those
ranks. Therefore, if the rank of the type that size_t is typedef for is
greater than the rank of int, the second paragraph applies, and the
usual arithmetic conversions will result in the int value being
converted to size_t before carrying out the operation.

The 3rd paragraph may apply and you can check
> using the preprocessor as in
> 
>     #if SIZE_MAX >= INT_MAX
>     .......
>     #else
>     .......
>     #endif
> 
> taking advantage of the stipulation "For the purposes of this token
> conversion and evaluation, all signed integer types and all unsigned integer
> types act as if they have the same representation as, respectively, the types
> intmax_t and uintmax_t defined in the header <stdint.h>." in "6.10.1
> Conditional inclusion" .So in the above context the C interpretation of
> SIZE_MAX >= INT_MAX    agrees with the mathematical interpretation.
> 
> But if the 3rd paragraph doesn't apply then for example in a situation  a+b
> where  a  is  int  with value 1 and  b  is  size_t  with value  SIZE_MAX-2
> then both will be converted to  unsigned int  and then the addition will be
> performed. So it won't be undefined behaviour but the expression won't have
> the mathematically correct result. Is my analysis correct ?

While you incorrectly concluded that neither of the first two paragraph
could apply, you are correct in your conclusions about what happens if
none of the first three paragraphs applies.

> ... If yes I find the
> outcome counterintuitive. Note that if both had been converted to  size_t
> then the expression would have the mathematically correct result.

Those rules are intended to determine what the result would be for any
pair of integer types. The usefulness of the final paragraph is made
less obvious by the fact that, if SIZE_MAX<INT_MAX, size_t would be
promoted to int before any of the other rules are applied.

Consider the case where size_t is a typedef for unsigned int, which is
guaranteed to not be promoted to int. If you add a long integer to an
unsigned int value, the current rules call for both operands to be
converted to unsigned long before adding them. What would you prefer to
happen in that case?

> Given the above , I think it would be more useful if the standard said
>     The rank of  size_t  will be greater than the rank of any other unsigned
>     integer type whose greatest value is less or equal than  SIZE_MAX .

That would prohibit an implementation from using unsigned int for size_t.

> All the above inspired a related question : are 2 distinct ranks always
> comparable or is it possible to have ranks R1 and R2 where none of the
> following applies :
>     - R1 is smaller than R2
>     - R2 is smaller than R1
>     - R1 and R2 are equal

I'm quite positive that the standard intended for ranks to always be
comparable - but offhand I've been unable to find a rule that would be
violated by an implementation which had ranks that could not be
compared. I'm much more reliably accurate when I say "I've found a
problem" than I am when I say "I can't find a problem".

[toc] | [prev] | [next] | [standalone]


#152510 — Re: What is the rank of size_t ?

FromSpiros Bousbouras <spibou@gmail.com>
Date2020-05-27 19:03 +0000
SubjectRe: What is the rank of size_t ?
Message-ID<G4VDkHapjhgoQ0Hlk@bongo-ra.co>
In reply to#152505
On Wed, 27 May 2020 09:59:50 -0400
James Kuyper <jameskuyper@alumni.caltech.edu> wrote:
> On 5/27/20 8:49 AM, Spiros Bousbouras wrote:
> > Specifically , if  a  has type  int  and  b  has type  size_t , can
> > a + b  overflow i.e. cause undefined behaviour ?
> > 
> 
> size_t is a typedef, and the only portable guarantee you have is that
> it's a typedef for an unsigned integer type with a maximum value no less
> than 65535; it could even be unsigned char, if CHAR_BIT >= 16.

How does it follow that it has to be a  typedef ? I looked at various places
in the standard and the only relevant information I see is that  size_t  has
to be defined in certain standard headers. It seems to me that an
implementation is allowed , whenever one of these standard headers has been
#include -ed ,  to set an internal flag which says that  size_t  has been
defined and  size_t  need not even appear at all in those headers.

[Replying to  <ram041$n9f$1@dont-email.me>]

> Consider the case where size_t is a typedef for unsigned int, which is
> guaranteed to not be promoted to int. If you add a long integer to an
> unsigned int value, the current rules call for both operands to be
> converted to unsigned long before adding them. What would you prefer to
> happen in that case?

If "long integer"  means  long int  then , if  long int  can represent all
the values of  unsigned int  then the  unsigned int  will be converted to
long int ; otherwise both will be converted to  unsigned long .Anyway , my
general preference is that , as long as backwards compatibility is maintained
, the conversions should be such that integer expressions have the
mathematically correct result as often as possible. So in the example where

    long int a = 1 ;
    size_t b = SIZE_MAX-2 ;

a+b  will have the mathematically correct result in both scenarios.

-- 
I always thought a "right" was a made-up social convention, and a "natural right"
was a made-up social convention that we deny we ever made up.
  James R. Dew

[toc] | [prev] | [next] | [standalone]


#152513 — Re: What is the rank of size_t ?

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2020-05-27 18:09 -0400
SubjectRe: What is the rank of size_t ?
Message-ID<ramoed$v38$1@dont-email.me>
In reply to#152510
On 5/27/20 3:03 PM, Spiros Bousbouras wrote:
> On Wed, 27 May 2020 09:59:50 -0400
> James Kuyper <jameskuyper@alumni.caltech.edu> wrote:
>> On 5/27/20 8:49 AM, Spiros Bousbouras wrote:
>>> Specifically , if  a  has type  int  and  b  has type  size_t , can
>>> a + b  overflow i.e. cause undefined behaviour ?
>>>
>>
>> size_t is a typedef, and the only portable guarantee you have is that
>> it's a typedef for an unsigned integer type with a maximum value no less
>> than 65535; it could even be unsigned char, if CHAR_BIT >= 16.
> 
> How does it follow that it has to be a  typedef ?

Strictly speaking, it doesn't have to be. Making a typedef is just the
simplest and AFAICT the most common way of implementing it. Nothing I
said depends upon how it is implemented, only on the fact that it is an
integer type.

>> Consider the case where size_t is a typedef for unsigned int, which is
>> guaranteed to not be promoted to int. If you add a long integer to an
>> unsigned int value, the current rules call for both operands to be
>> converted to unsigned long before adding them. What would you prefer to
>> happen in that case?
> 
> If "long integer"  means  long int  then , if  long int  can represent all
> the values of  unsigned int

Sorry - I was sloppy constructing my example. I wanted to specify a
situation where only the last paragraph applies, but I forgot to mention
that I'm talking about an implementation where int and long are the same
size, which is needed to prevent the third paragraph from applying.

>  then the  unsigned int  will be converted to
> long int ; otherwise both will be converted to  unsigned long .Anyway , my
> general preference is that , as long as backwards compatibility is maintained
> , the conversions should be such that integer expressions have the
> mathematically correct result as often as possible. So in the example where
> 
>     long int a = 1 ;
>     size_t b = SIZE_MAX-2 ;
> 
> a+b  will have the mathematically correct result in both scenarios.

If a is negative and b is smaller than the magnitude of a, then the
mathematical value of a+b is negative. If LONG_MAX < SIZE_MAX, the C
result will have the type unsigned long, which can't represent the
mathematically correct value.

[toc] | [prev] | [next] | [standalone]


#152534

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2020-05-30 01:54 -0700
Message-ID<864krxssyz.fsf@linuxsc.com>
In reply to#152500
Spiros Bousbouras <spibou@gmail.com> writes:

> On Wed, 27 May 2020 12:49:41 GMT
> Spiros Bousbouras <spibou@gmail.com> wrote:
>
>> Specifically , if a has type int and b has type size_t , can a + b
>> overflow i.e. cause undefined behaviour ?
>
> Let me expand on the question.  First I will quote "6.3.1.8 Usual
> arithmetic conversions" :
>
>     Otherwise, the integer promotions are performed on both
>     operands.  Then the following rules are applied to the promoted
>     operands:
>
>       If both operands have the same type, then no further
>       conversion is needed.  Otherwise, if both operands have signed
>       integer types or both have unsigned integer types, the operand
>       with the type of lesser integer conversion rank is converted
>       to the type of the operand with greater rank.
>
>       Otherwise, if the operand that has unsigned integer type has
>       rank greater or equal to the rank of the type of the other
>       operand, then the operand with signed integer type is
>       converted to the type of the operand with unsigned integer
>       type.
>
>       Otherwise, if the type of the operand with signed integer type
>       can represent all of the values of the type of the operand
>       with unsigned integer type, then the operand with unsigned
>       integer type is converted to the type of the operand with
>       signed integer type.
>
>       Otherwise, both operands are converted to the unsigned integer
>       type corresponding to the type of the operand with signed
>       integer type.
>
> The first 2 paragraphs don't apply because the standard doesn't say
> anything about the rank of size_t .

(Note that the "first paragraph" is actually two paragraphs in
the Standard.  But I will use the text as written above.)

The first paragraph /may/ apply if size_t has a conversion rank
less than int.  If so, then size_t could have been promoted to
int, so both types are int, and the addition is done in type
int, which can overflow.

The second paragraph /may/ apply but we don't know if it does apply
because we don't know whether (a) size_t has a conversion rank
less than int but was promoted to unsigned int, or (b) size_t has
a conversion rank greater than or equal to int.  If the second
paragraph applies, then no overflow is possible.

Note that size_t does have an integer conversion rank even if we
don't know what it is.

> The 3rd paragraph may apply

When the type of 'a' is int the third paragraph /cannot/ apply
because one of the first two paragraphs must apply even though we
don't know which one does.  This conclusion follows from the
lead-in sentence that says "the integer promotions are performed
on both operands."

When the type of 'a' is long the third paragraph may apply, so
let's proceed on that basis.

> and you can check using the preprocessor
> as in
>
>     #if SIZE_MAX >= LONG_MAX  [changed from INT_MAX]
>     .......
>     #else
>     .......
>     #endif
>
> taking advantage of the stipulation "For the purposes of this token
> conversion and evaluation, all signed integer types and all unsigned
> integer types act as if they have the same representation as,
> respectively, the types intmax_t and uintmax_t defined in the header
> <stdint.h>." in "6.10.1 Conditional inclusion" .So in the above
> context the C interpretation of SIZE_MAX >= INT_MAX agrees with the
> mathematical interpretation.

First, we don't need the preprocessor rules.  Conversion rules
for integer types guarantee that non-negative values are
unchanged, so any relation such as SIZE_MAX >= LONG_MAX will
always give the same result as the mathematical result.

However, the test is wrong.  If SIZE_MAX > LONG_MAX, then the
conversion rank of size_t must be at least as large as the
conversion rank of long, so the long operand will be converted to
type size_t.  If SIZE_MAX < LONG_MAX, then the conversion rank of
size_t must be less than the conversion rank of long, so the
addition will be done in type long, which could overflow.  The
last case is the interesting one.  If SIZE_MAX == LONG_MAX, then
the conversion rank of size_t may be less than the conversion
rank of long, or it may be greater than or equal to long's
conversion rank.  There is a test that can be done to see which
of these cases hold -- that is, whether overflow is possible --
although the test cannot be done in the preprocessor.  That test
is this:

  (0 ? a+b : -1) < 0 ? "may overflow" : "overflow not possible"

This test works because -1 is converted either to a signed type
or an unsigned type.  If it is converted to a signed type, it
will still be -1, hence less than 0, hence "may overflow".  If it
is converted to an unsigned type, whatever the value is the value
will /not/ be less than 0, hence "overflow not possible".

> But if the 3rd paragraph doesn't apply then for example in a
> situation a+b where a is int with value 1 and b is size_t with value
> SIZE_MAX-2 then both will be converted to unsigned int and then the
> addition will be performed.  So it won't be undefined behaviour but
> the expression won't have the mathematically correct result.  Is my
> analysis correct ?

   1 + (SIZE_MAX-2) == SIZE_MAX-1

I don't see why you think the expression won't have the same
result as the mathematically correct value.  It does.  Are you
talking about different values?

> If yes I find the outcome counterintuitive.  Note
> that if both had been converted to size_t then the expression would
> have the mathematically correct result.
>
> Given the above , I think it would be more useful if the standard
> said
>     The rank of size_t will be greater than the rank of any other
>     unsigned integer type whose greatest value is less or equal than
>     SIZE_MAX .

This rule isn't strong enough to give you the guarantees you
want.  Any should at least guarantee that size_t cannot
promote to int, which this rule does not.

> In the scenarios I can think of , such a stipulation would make it
> easier for programmers to reason about their code , would give more
> intuitive results (according to my intuition anyway) and would give
> no additional burden to implementations since likely they behave
> like this already.

If one is worried about such things, it better just not to use
size_t directly.  For example:

    #if SIZE_MAX > ULONG_MAX
       typedef size_t Size;
    #else
       typedef unsigned long Size;
    #endif

after which just use 'Size' rather than size_t.  As long as other
operands are 'long' or smaller, no overflow is possible.

> All the above inspired a related question : are 2 distinct ranks
> always comparable or is it possible to have ranks R1 and R2 where
> none of the following applies :
>     - R1 is smaller than R2
>     - R2 is smaller than R1
>     - R1 and R2 are equal
>
> ? I'm not sure if it's relevant to anything but it seems complicated
> to examine all combinations of ranks and conversion rules to see if
> it might be relevant so , unless there is a specific situation where
> it would be useful to have ranks which are incomparable , it would
> be better if the standard said that they are always comparable.

We know that integer conversion ranks are fully ordered because
of the provision in 6.2.5 p8:

    For any two integer types with the same signedness and
    different integer conversion rank (see 6.3.1.1), the range
    of values of the type with smaller integer conversion rank
    is a subrange of the values of the other type.

If two types have different integer conversion ranks, then one
conversion rank is smaller than the other.  Done.

[toc] | [prev] | [next] | [standalone]


#152501 — Re: What is the rank of size_t ?

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2020-05-27 09:59 -0400
SubjectRe: What is the rank of size_t ?
Message-ID<ralron$p47$1@dont-email.me>
In reply to#152499
On 5/27/20 8:49 AM, Spiros Bousbouras wrote:
> Specifically , if  a  has type  int  and  b  has type  size_t , can
> a + b  overflow i.e. cause undefined behaviour ?
> 

size_t is a typedef, and the only portable guarantee you have is that
it's a typedef for an unsigned integer type with a maximum value no less
than 65535; it could even be unsigned char, if CHAR_BIT >= 16. The only
unsigned integer type it can't be is _Bool, because of the special
semantics attached to _Bool. It's rank depends upon which type is a
typedef for. If writing code where it matters, you can compare SIZE_MAX
with the corresponding maximum value of the unsigned version of other
type you're interested in - if they differ, the one that is larger must
have a higher rank. If they're the same, then you can use a _Generic()
expression to determine which one has the larger rank:

    _Generic((size_t)1 + 1U, size_t:true, default:false)

That value will be false only if unsigned int has a higher rank than
size_t. Unsigned int is required to have the same rank as int.

Note: unless you have ruled out the possibility that size_t is different
from int, you cannot put both size_t and int in the same _Generic()
expression - if they are the same type, it wouldn't know which one to
use, which is why that is a constraint violation (6.5.1.1p2).

As a practical matter, however, it is very common for size_t to have a
rank no less than that of int, which is sufficient that you don't have
to worry about it promoting to int, nor about it being converted to int
by the usual arithmetic conversions. This is partly because it does
avoid those problems, but it's also usually the case that no type with a
rank lower than that of int has sufficient range to be usable as size_t.

[toc] | [prev] | [next] | [standalone]


#152503 — Re: What is the rank of size_t ?

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2020-05-27 07:37 -0700
SubjectRe: What is the rank of size_t ?
Message-ID<87wo4xxx3s.fsf@nosuchdomain.example.com>
In reply to#152501
James Kuyper <jameskuyper@alumni.caltech.edu> writes:
[...]
> Note: unless you have ruled out the possibility that size_t is different
> from int, you cannot put both size_t and int in the same _Generic()
> expression - if they are the same type, it wouldn't know which one to
> use, which is why that is a constraint violation (6.5.1.1p2).
[...]

Did you mean "different from unsigned int"?

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#152504 — Re: What is the rank of size_t ?

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2020-05-27 11:02 -0400
SubjectRe: What is the rank of size_t ?
Message-ID<ralver$iuu$1@dont-email.me>
In reply to#152503
On 5/27/20 10:37 AM, Keith Thompson wrote:
> James Kuyper <jameskuyper@alumni.caltech.edu> writes:
> [...]
>> Note: unless you have ruled out the possibility that size_t is different
>> from int, you cannot put both size_t and int in the same _Generic()
>> expression - if they are the same type, it wouldn't know which one to
>> use, which is why that is a constraint violation (6.5.1.1p2).
> [...]
> 
> Did you mean "different from unsigned int"?

My comment was wrong for several reasons, but that fix doesn't cover all
of the problems with it.
1. I meant to say "same as" rather than "different from" (or
"guaranteed" rather than "ruled out").
2. I should have said "compatible with" rather than "same as", and
"compatible types" rather than "the same type".

[toc] | [prev] | [next] | [standalone]


#152511 — Re: What is the rank of size_t ?

FromVir Campestris <vir.campestris@invalid.invalid>
Date2020-05-27 20:46 +0100
SubjectRe: What is the rank of size_t ?
Message-ID<ramg25$3lp$1@dont-email.me>
In reply to#152501
On 27/05/2020 14:59, James Kuyper wrote:
> size_t is a typedef, and the only portable guarantee you have is that
> it's a typedef for an unsigned integer type with a maximum value no less
> than 65535;

Must it be a typedef for one of the common types?

It occurs to me that there are some architectures where the address 
space size is not a common integer. Some of the 8086 modes, for example, 
will allow a megabyte of address space (20 bit).

Andy

[toc] | [prev] | [next] | [standalone]


#152512 — Re: What is the rank of size_t ?

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2020-05-27 14:30 -0700
SubjectRe: What is the rank of size_t ?
Message-ID<87sgflxe07.fsf@nosuchdomain.example.com>
In reply to#152511
Vir Campestris <vir.campestris@invalid.invalid> writes:
> On 27/05/2020 14:59, James Kuyper wrote:
>> size_t is a typedef, and the only portable guarantee you have is that
>> it's a typedef for an unsigned integer type with a maximum value no less
>> than 65535;
>
> Must it be a typedef for one of the common types?

No, it can be a typedef for an extended integer type.

> It occurs to me that there are some architectures where the address
> space size is not a common integer. Some of the 8086 modes, for
> example, will allow a megabyte of address space (20 bit).

Such a system will typically make size_t bigger than it strictly needs
to be.  An implementation for an 8086 can provide 32-bit integers much
more easily than it can provide 20-bit integers.

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#152514 — Re: What is the rank of size_t ?

FromReal Troll <real.troll@trolls.com>
Date2020-05-28 06:35 -1000
SubjectRe: What is the rank of size_t ?
Message-ID<raop58$1hn8$1@gioia.aioe.org>
In reply to#152499
On 27/05/2020 13:49, Spiros Bousbouras wrote:
> Specifically , if  a  has type  int  and  b  has type  size_t , can
> a + b  overflow i.e. cause undefined behaviour ?

Try running this program to see what happens?  I use 64 bit compiler on 
a 64 bit machine:

<******************************************************************>

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <float.h>

int main(void)
{
     const size_t N = 18446744073709551615;
     int a = 100;
     size_t result = N + a;
     printf("SIZE_MAX is: = %zu\n", SIZE_MAX);
     printf("Value of result (N + a) = %zu\n", result);

     return 0;
}

<******************************************************************>



[toc] | [prev] | [next] | [standalone]


#152529 — Re: What is the rank of size_t ?

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2020-05-29 20:55 -0700
SubjectRe: What is the rank of size_t ?
Message-ID<86pnamrs9r.fsf@linuxsc.com>
In reply to#152514
Real Troll <real.troll@trolls.com> writes:

> On 27/05/2020 13:49, Spiros Bousbouras wrote:
>
>> Specifically , if  a  has type  int  and  b  has type  size_t , can
>> a + b  overflow i.e. cause undefined behaviour ?
>
> Try running this program to see what happens?  I use 64 bit compiler on
> a 64 bit machine:
>
> <******************************************************************>
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <limits.h>
> #include <float.h>
>
> int main(void)
> {
>   const size_t N = 18446744073709551615;
>   int a = 100;
>   size_t result = N + a;
>   printf("SIZE_MAX is: = %zu\n", SIZE_MAX);
>   printf("Value of result (N + a) = %zu\n", result);
>
>   return 0;
> }
>
> <******************************************************************>

Do you get two program errors?  That's what I get.

[toc] | [prev] | [next] | [standalone]


#152541 — Re: What is the rank of size_t ?

FromReal Troll <Real.Troll@trolls.com>
Date2020-05-30 08:05 -1000
SubjectRe: What is the rank of size_t ?
Message-ID<rau761$8og$1@gioia.aioe.org>
In reply to#152529
On 30/05/2020 04:55, Tim Rentsch wrote:
> Real Troll <real.troll@trolls.com> writes:
>
>> On 27/05/2020 13:49, Spiros Bousbouras wrote:
>>
>>> Specifically , if  a  has type  int  and  b  has type  size_t , can
>>> a + b  overflow i.e. cause undefined behaviour ?
>> Try running this program to see what happens?  I use 64 bit compiler on
>> a 64 bit machine:
>>
>> <******************************************************************>
>>
>> #include <stdio.h>
>> #include <stdlib.h>
>> #include <limits.h>
>> #include <float.h>
>>
>> int main(void)
>> {
>>    const size_t N = 18446744073709551615;
>>    int a = 100;
>>    size_t result = N + a;
>>    printf("SIZE_MAX is: = %zu\n", SIZE_MAX);
>>    printf("Value of result (N + a) = %zu\n", result);
>>
>>    return 0;
>> }
>>
>> <******************************************************************>
> Do you get two program errors?  That's what I get.

No errors in Visual Studio 2019.  The command I used for quite simple:

cl test.c

Then I ran the program and got 99 for the result which indicates after 
the Size_Max the counter reverted to 0 to 99 as expected like n an array 
situation.

[toc] | [prev] | [next] | [standalone]


#152577 — Re: What is the rank of size_t ?

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2020-05-31 17:33 -0700
SubjectRe: What is the rank of size_t ?
Message-ID<86k10rpqum.fsf@linuxsc.com>
In reply to#152541
Real Troll <Real.Troll@trolls.com> writes:

> On 30/05/2020 04:55, Tim Rentsch wrote:
>
>> Real Troll <real.troll@trolls.com> writes:
>>
>>> On 27/05/2020 13:49, Spiros Bousbouras wrote:
>>>
>>>> Specifically , if  a  has type  int  and  b  has type  size_t , can
>>>> a + b  overflow i.e. cause undefined behaviour ?
>>>
>>> Try running this program to see what happens?  I use 64 bit compiler on
>>> a 64 bit machine:
>>>
>>> <******************************************************************>
>>>
>>> #include <stdio.h>
>>> #include <stdlib.h>
>>> #include <limits.h>
>>> #include <float.h>
>>>
>>> int main(void)
>>> {
>>>    const size_t N = 18446744073709551615;
>>>    int a = 100;
>>>    size_t result = N + a;
>>>    printf("SIZE_MAX is: = %zu\n", SIZE_MAX);
>>>    printf("Value of result (N + a) = %zu\n", result);
>>>
>>>    return 0;
>>> }
>>>
>>> <******************************************************************>
>>
>> Do you get two program errors?  That's what I get.
>
> No errors in Visual Studio 2019.  [...]

Well that explains at least some of it.  What do you get if
you run this:

    #include <stdio.h>
    #include <stdint.h>

    int
    main(){
        printf( "INTMAX_MAX is %td\n", INTMAX_MAX );
        return  0;
    }

?

[toc] | [prev] | [next] | [standalone]


#152579 — Re: What is the rank of size_t ?

FromReal Troll <real.troll@trolls.com>
Date2020-06-01 01:45 -1000
SubjectRe: What is the rank of size_t ?
Message-ID<rb2ppj$155s$1@gioia.aioe.org>
In reply to#152577
On 01/06/2020 01:33, Tim Rentsch wrote:
> Real Troll <Real.Troll@trolls.com> writes:
>
>> On 30/05/2020 04:55, Tim Rentsch wrote:
>>
>>> Real Troll <real.troll@trolls.com> writes:
>>>
>>>> On 27/05/2020 13:49, Spiros Bousbouras wrote:
>>>>
>>>>> Specifically , if  a  has type  int  and  b  has type  size_t , can
>>>>> a + b  overflow i.e. cause undefined behaviour ?
>>>> Try running this program to see what happens?  I use 64 bit compiler on
>>>> a 64 bit machine:
>>>>
>>>> <******************************************************************>
>>>>
>>>> #include <stdio.h>
>>>> #include <stdlib.h>
>>>> #include <limits.h>
>>>> #include <float.h>
>>>>
>>>> int main(void)
>>>> {
>>>>     const size_t N = 18446744073709551615;
>>>>     int a = 100;
>>>>     size_t result = N + a;
>>>>     printf("SIZE_MAX is: = %zu\n", SIZE_MAX);
>>>>     printf("Value of result (N + a) = %zu\n", result);
>>>>
>>>>     return 0;
>>>> }
>>>>
>>>> <******************************************************************>
>>> Do you get two program errors?  That's what I get.
>> No errors in Visual Studio 2019.  [...]
> Well that explains at least some of it.  What do you get if
> you run this:
>
>      #include <stdio.h>
>      #include <stdint.h>
>
>      int
>      main(){
>          printf( "INTMAX_MAX is %td\n", INTMAX_MAX );
>          return  0;
>      }
>
> ?

On a 64 bit machine using 64 bit compiler:

INTMAX_MAX is 9223372036854775807


For 32 bit compiler (on 64 bit machine), I was getting errors but I made 
small changes and I got:

INTMAX_MAX is 9223372036854775807

The changes I made were:

printf("INTMAX_MAX is %I64d\n", INTMAX_MAX);
printf("INTMAX_MAX is %lld\n", INTMAX_MAX);

[toc] | [prev] | [next] | [standalone]


#152650 — Re: What is the rank of size_t ?

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2020-06-03 11:33 -0700
SubjectRe: What is the rank of size_t ?
Message-ID<86367cov78.fsf@linuxsc.com>
In reply to#152579
Real Troll <real.troll@trolls.com> writes:

> On 01/06/2020 01:33, Tim Rentsch wrote:
>
>> Real Troll <Real.Troll@trolls.com> writes:
>>
>>> On 30/05/2020 04:55, Tim Rentsch wrote:
>>>
>>>> Real Troll <real.troll@trolls.com> writes:
>>>>
>>>>> On 27/05/2020 13:49, Spiros Bousbouras wrote:
>>>>>
>>>>>> Specifically , if  a  has type  int  and  b  has type  size_t , can
>>>>>> a + b  overflow i.e. cause undefined behaviour ?
>>>>>
>>>>> Try running this program to see what happens?  I use 64 bit compiler on
>>>>> a 64 bit machine:
>>>>>
>>>>> <******************************************************************>
>>>>>
>>>>> #include <stdio.h>
>>>>> #include <stdlib.h>
>>>>> #include <limits.h>
>>>>> #include <float.h>
>>>>>
>>>>> int main(void)
>>>>> {
>>>>>     const size_t N = 18446744073709551615;
>>>>>     int a = 100;
>>>>>     size_t result = N + a;
>>>>>     printf("SIZE_MAX is: = %zu\n", SIZE_MAX);
>>>>>     printf("Value of result (N + a) = %zu\n", result);
>>>>>
>>>>>     return 0;
>>>>> }
>>>>>
>>>>> <******************************************************************>
>>>>
>>>> Do you get two program errors?  That's what I get.
>>>
>>> No errors in Visual Studio 2019.  [...]
>>
>> Well that explains at least some of it.  What do you get if
>> you run this:
>>
>>      #include <stdio.h>
>>      #include <stdint.h>
>>
>>      int
>>      main(){
>>          printf( "INTMAX_MAX is %td\n", INTMAX_MAX );
>>          return  0;
>>      }
>>
>> ?

As Ike Naar noted, the conversion sequence %td should instead
have been %jd.

> On a 64 bit machine using 64 bit compiler:
>
> INTMAX_MAX is 9223372036854775807
>
>
> For 32 bit compiler (on 64 bit machine), I was getting errors but I made
> small changes and I got:
>
> INTMAX_MAX is 9223372036854775807
>
> The changes I made were:
>
> printf("INTMAX_MAX is %I64d\n", INTMAX_MAX);
> printf("INTMAX_MAX is %lld\n", INTMAX_MAX);

Oh yes, the famous %I64d.  I expect both of these give an
accurate output for the value.

Armed with these new facts, we may conclude the Visual Studio
implementation is not conforming, in two different ways.  The
first is that 18446744073709551615 is accepted as a decimal
constant, even though it is larger than 9223372036854775807,
which is the largest value of the largest signed type.  Writing
the constant 18446744073709551615 without a trailing u or U
should have been given a diagnostic.

The second is that SIZE_MAX is allowed as a (defined) identifier,
even though <stdint.h> has not been included.  Only <stdint.h>
may define SIZE_MAX.  The use of SIZE_MAX without <stdint.h>
having been included also merits a diagnostic.

[toc] | [prev] | [next] | [standalone]


#152582 — Re: What is the rank of size_t ?

FromIke Naar <ike@otaku.sdf.org>
Date2020-06-01 20:51 +0000
SubjectRe: What is the rank of size_t ?
Message-ID<slrn3ifkrdaqio.3t3.ike@otaku.sdf.org>
In reply to#152577
On 2020-06-01, Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
> Well that explains at least some of it.  What do you get if
> you run this:
>
>     #include <stdio.h>
>     #include <stdint.h>
>
>     int
>     main(){
>         printf( "INTMAX_MAX is %td\n", INTMAX_MAX );

Why use %td (which applies to an argument of type ptrdiff_t),
instead of %jd (which applies to an argument of type intmax_t)?

>         return  0;
>     }
>
> ?

[toc] | [prev] | [next] | [standalone]


#152649 — Re: What is the rank of size_t ?

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2020-06-03 11:16 -0700
SubjectRe: What is the rank of size_t ?
Message-ID<867dwoow0n.fsf@linuxsc.com>
In reply to#152582
Ike Naar <ike@otaku.sdf.org> writes:

> On 2020-06-01, Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
>
>> Well that explains at least some of it.  What do you get if
>> you run this:
>>
>>     #include <stdio.h>
>>     #include <stdint.h>
>>
>>     int
>>     main(){
>>         printf( "INTMAX_MAX is %td\n", INTMAX_MAX );
>
> Why use %td (which applies to an argument of type ptrdiff_t),
> instead of %jd (which applies to an argument of type intmax_t)?

Because

  (1) I don't use either often enough to remember which is
      which, and I confused the two;

  (2) I didn't bother (even though I usually do, I didn't
      this time) to check the Standard to be sure;  and

  (3) I got a false positive from gcc as a result of
      intmax_t and ptrdiff_t having the same underlying
      type, so test compiling the program didn't give a
      -Wformat diagnostic.

[toc] | [prev] | [next] | [standalone]


#152565 — Re: What is the rank of size_t ?

Fromraltbos@xs4all.nl (Richard Bos)
Date2020-05-31 09:12 +0000
SubjectRe: What is the rank of size_t ?
Message-ID<5ed3739b.629390@news.xs4all.nl>
In reply to#152514
Real Troll <real.troll@trolls.com> wrote:

> On 27/05/2020 13:49, Spiros Bousbouras wrote:
> > Specifically , if  a  has type  int  and  b  has type  size_t , can
> > a + b  overflow i.e. cause undefined behaviour ?
> 
> Try running this program to see what happens?

"Try running this" is a useless answer in response to a question about
possible undefined behavious, I'm afraid. 
It may show that, on the implementation used, it behaves unexpectedly;
that proves that either the code has UB or the implementation is
non-conforming. 
It may also show that, on the implementation used, it behaves as if
there is no UB; that proves that either the code had no UB in the first
place, or the implementation happens to let this UB behave as if it were
defined - which is one of the allowed results of UB! - or most likely,
and the presumable reasons Spiros asked this question, that it can have
defined or undefined behaviour depending on the sizes of the types.
And even worse, in the first case, it only shows that it has UB _on that
implementation_. This has consequences for portable code, but it may
still be possible to prove defined behavious for _some_ implementations,
including all the target ones.

So no, "try it" is meaningless in the face of UB.

Richard

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.c


csiph-web