Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #152499 > unrolled thread
| Started by | Spiros Bousbouras <spibou@gmail.com> |
|---|---|
| First post | 2020-05-27 12:49 +0000 |
| Last post | 2020-06-02 10:06 +0200 |
| Articles | 20 on this page of 25 — 11 participants |
Back to article view | Back to comp.lang.c
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 →
| From | Spiros Bousbouras <spibou@gmail.com> |
|---|---|
| Date | 2020-05-27 12:49 +0000 |
| Subject | What 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]
| From | Spiros Bousbouras <spibou@gmail.com> |
|---|---|
| Date | 2020-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]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2020-05-27 11:14 -0400 |
| Subject | Re: 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]
| From | Spiros Bousbouras <spibou@gmail.com> |
|---|---|
| Date | 2020-05-27 19:03 +0000 |
| Subject | Re: 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]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2020-05-27 18:09 -0400 |
| Subject | Re: 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]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2020-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]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2020-05-27 09:59 -0400 |
| Subject | Re: 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]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2020-05-27 07:37 -0700 |
| Subject | Re: 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]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2020-05-27 11:02 -0400 |
| Subject | Re: 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]
| From | Vir Campestris <vir.campestris@invalid.invalid> |
|---|---|
| Date | 2020-05-27 20:46 +0100 |
| Subject | Re: 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]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2020-05-27 14:30 -0700 |
| Subject | Re: 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]
| From | Real Troll <real.troll@trolls.com> |
|---|---|
| Date | 2020-05-28 06:35 -1000 |
| Subject | Re: 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]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2020-05-29 20:55 -0700 |
| Subject | Re: 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]
| From | Real Troll <Real.Troll@trolls.com> |
|---|---|
| Date | 2020-05-30 08:05 -1000 |
| Subject | Re: 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]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2020-05-31 17:33 -0700 |
| Subject | Re: 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]
| From | Real Troll <real.troll@trolls.com> |
|---|---|
| Date | 2020-06-01 01:45 -1000 |
| Subject | Re: 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]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2020-06-03 11:33 -0700 |
| Subject | Re: 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]
| From | Ike Naar <ike@otaku.sdf.org> |
|---|---|
| Date | 2020-06-01 20:51 +0000 |
| Subject | Re: 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]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2020-06-03 11:16 -0700 |
| Subject | Re: 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]
| From | raltbos@xs4all.nl (Richard Bos) |
|---|---|
| Date | 2020-05-31 09:12 +0000 |
| Subject | Re: 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