I wasn't able to find an answer to the following questions in a draft
version of IOS 989999. What is the semantic when you decrement an
unsigned int below 0 (or subtract two unsigned ints with negative
result)? AFAIR, this results in implementationdefined behavior but
not undefined behavior. Is that correct?
So what does the standard say to this code?
void f(void)
{
unsigned int n = 0;
n;
}
Also, do I have implementationdefined or undefined behavior, if I
decrement below zero but don't use the value, as in the following
code?
void f(unsigned int n)
{
while (n 0) { /* In the last loop iteration, n is
; decremented from 0, but not used
} afterwards */
}
A short notice with section number in the standard would be nice
(as I think section numbering in my draft version is not that
different).
urs 13 9551
On Mon, 08 Sep 2008 14:38:16 +0200, Urs Thuermann wrote:
So what does the standard say to this code?
unsigned int n = 0;
n;
Always results in UINT_MAX.
Also, do I have implementationdefined or undefined behavior, if I
decrement below zero but don't use the value, as in the following code?
void f(unsigned int n)
{
while (n 0) { /* In the last loop iteration, n is
; decremented from 0, but not used
} afterwards */
}
This evaluates the greaterthan with the original value of n, then
decrements n. n is automatic so its value is lost when the function
returns.
Urs Thuermann wrote:
I wasn't able to find an answer to the following questions in a draft
version of IOS 989999. What is the semantic when you decrement an
unsigned int below 0 (or subtract two unsigned ints with negative
result)? AFAIR, this results in implementationdefined behavior but
not undefined behavior. Is that correct?
No. It is standarddefined behavior. Section 6.2.5p9 says:
"A computation involving unsigned operands can never overflow, because
a result that cannot be represented by the resulting unsigned integer
type is reduced modulo the number that is one greater than the largest
value that can be represented by the resulting type."
So what does the standard say to this code?
void f(void)
{
unsigned int n = 0;
n;
At this point, the value of n must be UINT_MAX.
}
Also, do I have implementationdefined or undefined behavior, if I
decrement below zero but don't use the value, as in the following
code?
void f(unsigned int n)
{
while (n 0) { /* In the last loop iteration, n is
; decremented from 0, but not used
} afterwards */
}
Since the behavior is standarddefined, you don't have to worry about
it; whether or not the resulting value gets used doesn't matter. If
the behavior were undefined (as, for example, INT_MAX+1), then the
fact that you didn't use the result still wouldn't protect your code,
at least in principle. As a practical matter, since the value is not
used, an optimizing compiler might remove the calculation that
produced the value, reducing the opportunities for undesireable
consequences  but you should never write code which relies upon this.
Urs Thuermann wrote:
>
I wasn't able to find an answer to the following questions in a
draft version of IOS 989999. What is the semantic when you
decrement an unsigned int below 0 (or subtract two unsigned ints
with negative result)? AFAIR, this results in implementation
defined behavior but not undefined behavior. Is that correct?
No. It is carefully defined. Unsigned quantities do arithmetic
modulo the (maximum unsigned value + 1).

[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Urs Thuermann <ur*@isnogud.escape.dewrites:
I wasn't able to find an answer to the following questions in a draft
version of IOS 989999.
<snip>
A short notice with section number in the standard would be nice
(as I think section numbering in my draft version is not that
different).
Mostly answered except for this bit. The main rule at work is 6.3.1.3
paragraph 2.

Ben. ja*********@verizon.net wrote:
Urs Thuermann wrote:
>I wasn't able to find an answer to the following questions in a draft version of IOS 989999. What is the semantic when you decrement an unsigned int below 0 (or subtract two unsigned ints with negative result)? AFAIR, this results in implementationdefined behavior but not undefined behavior. Is that correct?
No.
Yes.
It is standarddefined behavior. Section 6.2.5p9 says:
"A computation involving unsigned operands can never overflow, because
a result that cannot be represented by the resulting unsigned integer
type is reduced modulo the number that is one greater than the largest
value that can be represented by the resulting type."
Note the part beginning "the largest value ...". That
value is implementationdefined, hence the value of the
result is implementationdefined.

Eric Sosman es*****@ieeedotorg.invalid
On Sun, 14 Sep 2008 17:20:16 0400, Eric Sosman
<es*****@ieeedotorg.invalidwrote:
>ja*********@verizon.net wrote:
>Urs Thuermann wrote:
>>I wasn't able to find an answer to the following questions in a draft version of IOS 989999. What is the semantic when you decrement an unsigned int below 0 (or subtract two unsigned ints with negative result)? AFAIR, this results in implementationdefined behavior but not undefined behavior. Is that correct?
No.
Yes.
>It is standarddefined behavior. Section 6.2.5p9 says:
"A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type."
Note the part beginning "the largest value ...". That value is implementationdefined, hence the value of the result is implementationdefined.
The value is implementation defined but the behavior is not. The
behavior is defined as quoted. Your approach would also render the
behavior of
int x = '0' < '1';
is also implementation defined since the values of '0' and '1' are
implementation dependent.

Remove del for email
Eric Sosman wrote:
ja*********@verizon.net wrote:
>Urs Thuermann wrote:
>>I wasn't able to find an answer to the following questions in a draft version of IOS 989999. What is the semantic when you decrement an unsigned int below 0 (or subtract two unsigned ints with negative result)? AFAIR, this results in implementationdefined behavior but not undefined behavior. Is that correct?
No.
Yes.
>It is standarddefined behavior. Section 6.2.5p9 says:
"A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type."
Note the part beginning "the largest value ...". That
value is implementationdefined, hence the value of the
result is implementationdefined.
No, that's implementationdependent result, but not
implementationdefined behavior. The implementation gets to decide for
each unsigned type what the value of TYPE_MAX is. Having made that
decision, they get no additional freedom in the value that results from
overflow or underflow for unsigned; there's a standarddefined
relationship between the two values.
Barry Schwarz wrote:
>
.... snip ...
>
The value is implementation defined but the behavior is not. The
behavior is defined as quoted. Your approach would also render
the behavior of
int x = '0' < '1';
is also implementation defined since the values of '0' and '1'
are implementation dependent.
However since '1' is known to have the value ('0' + 1) that x is
thoroughly defined. If you picked 'a' and 'b' I could agree.

[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section. ja*********@verizon.net writes:
No. It is standarddefined behavior. Section 6.2.5p9 says:
"A computation involving unsigned operands can never overflow, because
a result that cannot be represented by the resulting unsigned integer
type is reduced modulo the number that is one greater than the largest
value that can be represented by the resulting type."
OK, Thanx. I've read the 1989 edition of the standard 10 or so years
ago and I had in mind that this would result in implementationdefined
behavior, but I probably confused that with the signed integer case
(which also is not implementationdefined but undefined if I read the
the standard correctly).
void f(unsigned int n)
{
while (n 0) { /* In the last loop iteration, n is
; decremented from 0, but not used
} afterwards */
}
Since the behavior is standarddefined, you don't have to worry about
it; whether or not the resulting value gets used doesn't matter. If
the behavior were undefined (as, for example, INT_MAX+1), then the
fact that you didn't use the result still wouldn't protect your code,
at least in principle.
Yes, that is what I assumed also.
As a practical matter, since the value is not used, an optimizing
compiler might remove the calculation that produced the value,
reducing the opportunities for undesireable consequences  but you
should never write code which relies upon this.
Yes, of course. I had a function which does somthing similar to
void f(int n)
{
while (n >= 0)
do_something();
}
and I wanted to change the parameter n to unsigned int like this
void f(unsigned int n)
{
while (n 0)
do_something();
}
and then I wondered what happens when n is 0 in the last loop
iteration. But your answer did clarify this completely, thanks
again.
urs
On 17 Sep 2008 09:58:28 +0200, Urs Thuermann <ur*@isnogud.escape.de>
wrote:
>ja*********@verizon.net writes:
>No. It is standarddefined behavior. Section 6.2.5p9 says:
"A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type."
OK, Thanx. I've read the 1989 edition of the standard 10 or so years ago and I had in mind that this would result in implementationdefined behavior, but I probably confused that with the signed integer case (which also is not implementationdefined but undefined if I read the the standard correctly).
It was in C89 but no longer in C99.

Remove del for email
Barry Schwarz <sc******@dqel.comwrites:
On 17 Sep 2008 09:58:28 +0200, Urs Thuermann <ur*@isnogud.escape.de>
wrote:
>>ja*********@verizon.net writes:
>>No. It is standarddefined behavior. Section 6.2.5p9 says:
"A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type."
OK, Thanx. I've read the 1989 edition of the standard 10 or so years ago and I had in mind that this would result in implementationdefined behavior, but I probably confused that with the signed integer case (which also is not implementationdefined but undefined if I read the the standard correctly).
It was in C89 but no longer in C99.
It's undefined in both C89/C90 and C99.
C99 6.5p5:
If an _exceptional condition_ occurs during the evaluation of an
expression (that is, if the result is not mathematically defined
or not in the range of representable values for its type), the
behavior is undefined.
C90 has the same wording.
Perhaps you're thinking of C99's change in the semantics of
conversions. In C99, a conversion to a signed type of a value that
can't be represented in that type either yields an
implementationdefined result or raises an implementationdefined
signal (C99 6.3.1.3p3); in C90, the result is implementationdefined
(it couldn't raise a signal).
(Outofrange conversions to a floatingpoint type invoke undefined
behavior in both C90 and C99.)

Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
 Antony Jay and Jonathan Lynn, "Yes Minister"
On Wed, 17 Sep 2008 21:30:22 0700, Keith Thompson <ks***@mib.org>
wrote:
>Barry Schwarz <sc******@dqel.comwrites:
>On 17 Sep 2008 09:58:28 +0200, Urs Thuermann <ur*@isnogud.escape.de> wrote:
>>>ja*********@verizon.net writes:
No. It is standarddefined behavior. Section 6.2.5p9 says:
"A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type."
OK, Thanx. I've read the 1989 edition of the standard 10 or so years ago and I had in mind that this would result in implementationdefined behavior, but I probably confused that with the signed integer case (which also is not implementationdefined but undefined if I read the the standard correctly).
It was in C89 but no longer in C99.
It's undefined in both C89/C90 and C99.
C99 6.5p5:
If an _exceptional condition_ occurs during the evaluation of an
expression (that is, if the result is not mathematically defined
or not in the range of representable values for its type), the
behavior is undefined.
C90 has the same wording.
Perhaps you're thinking of C99's change in the semantics of conversions. In C99, a conversion to a signed type of a value that can't be represented in that type either yields an implementationdefined result or raises an implementationdefined signal (C99 6.3.1.3p3); in C90, the result is implementationdefined (it couldn't raise a signal).
(Outofrange conversions to a floatingpoint type invoke undefined behavior in both C90 and C99.)
But the thread (or at least what I could see of it) appeared to be
talking about converting an unsigned value to a signed integer and for
C99 the relevant paragraph seems to be 6.3.1.33 which says
"Otherwise, the new type is signed and the value cannot be represented
in it; either the result is implementationdefined or an
implementationdefined signal is raised."

Remove del for email
Barry Schwarz <sc******@dqel.comwrites:
On Wed, 17 Sep 2008 21:30:22 0700, Keith Thompson <ks***@mib.org>
wrote:
>>Barry Schwarz <sc******@dqel.comwrites:
>>On 17 Sep 2008 09:58:28 +0200, Urs Thuermann <ur*@isnogud.escape.de> wrote:
[...]
>>>>OK, Thanx. I've read the 1989 edition of the standard 10 or so years ago and I had in mind that this would result in implementationdefined behavior, but I probably confused that with the signed integer case (which also is not implementationdefined but undefined if I read the the standard correctly).
It was in C89 but no longer in C99.
It's undefined in both C89/C90 and C99.
C99 6.5p5:
If an _exceptional condition_ occurs during the evaluation of an expression (that is, if the result is not mathematically defined or not in the range of representable values for its type), the behavior is undefined.
C90 has the same wording.
Perhaps you're thinking of C99's change in the semantics of conversions. In C99, a conversion to a signed type of a value that can't be represented in that type either yields an implementationdefined result or raises an implementationdefined signal (C99 6.3.1.3p3); in C90, the result is implementationdefined (it couldn't raise a signal).
(Outofrange conversions to a floatingpoint type invoke undefined behavior in both C90 and C99.)
But the thread (or at least what I could see of it) appeared to be
talking about converting an unsigned value to a signed integer and for
C99 the relevant paragraph seems to be 6.3.1.33 which says
"Otherwise, the new type is signed and the value cannot be represented
in it; either the result is implementationdefined or an
implementationdefined signal is raised."
Then I'm unclear on what you meant by "It was in C89 but no longer in
C99." I thought you meant that something (outofrange conversion to
a signed type, probably) was undefined in C89, but is no longer
undefined in C99, which is not the case.

Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
 Antony Jay and Jonathan Lynn, "Yes Minister" This discussion thread is closed Replies have been disabled for this discussion. Similar topics
7 posts
views
Thread by Colin Brown 
last post: by

25 posts
views
Thread by Jason 
last post: by

16 posts
views
Thread by JKop 
last post: by

2 posts
views
Thread by MLH 
last post: by

5 posts
views
Thread by Subrahmanyam Arya 
last post: by

29 posts
views
Thread by Peter Ammon 
last post: by

39 posts
views
Thread by Frederick Gotham 
last post: by

23 posts
views
Thread by Hallvard B Furuseth 
last post: by

35 posts
views
Thread by Martin Wells 
last post: by
          