I read elsewhere that signed integer division was undefined in C, with
maybe a change having come in C99.
Is that true?
--
fred
Did you?
Could you indicate where this "elsewhere" was?
The semantics of signed integer division have changed, arguably -- it used
to be unspecified which of a couple of things happened in some cases, now
it's more consistent. But this only applied when there were negative numbers
involved -- signed positive numbers were always fine.
And of course, division by zero is still undefined.
-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet...@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
No, with Yes.
17 / 3 and 17 % 3 are and always have been well-defined,
evaluating to 5 and 2, respectively.
17 / -3 and 17 % -3 are also well-defined, and have been
ever since the ANSI Standard was adopted. But in that Standard
they could evaluate to -5 and -2 or to -6 and 1, the choice
being left to the implementation. The implementation had to
document its choice (and could not produce some third result),
so again the division operation was well-defined, although
(potentially) defined differently on different systems, just
as CHAR_MIN is zero on some systems, negative on others.
C99 *did* make a change: It removed the implementation's
freedom of choice. The results must now be -5 and -2, and the
pair -6 and 1 are forbidden. The operations are still defined.
Integer division or mod by zero, signed or unsigned, has
always been undefined. There's a rumor that the Committee is
considering making INT_MIN % -1 (which must now be 0) either
undefined or implementation-defined, I'm not sure which.
--
Eric Sosman
eso...@ieee-dot-org.invalid
It's undefined behavior if INT_MIN / -1 isn't representable, since most
machines either throw an exception or produce an unspecified result
(with an overflow indication) in that case. The Committee never
intended to require a result of zero, although that isn't stated
explicitly in the Standard.
--
Larry Jones
All this was funny until she did the same thing to me. -- Calvin
Current draft wording makes it undefined on machines with INT_MIN <
-INT_MAX. 6.5.5 p6 used to end:
"If the quotient a/b is representable, the expression (a/b)*b + a%b
shall equal a."
and now (unofficially) reads:
"If the quotient a/b is representable, the expression (a/b)*b + a%b
shall equal a; otherwise, the behavior of both a/b and a%b is
undefined."
--
Ben.
An interesting read. Beyond what Ben and Lawrence had to comment, I was
curious about this language:
> The implementation had to
> document its choice ....
Implementations have to document something? How general is this
requirement?
--
fred
That takes a little bit of head-scratching. I had to work a concrete
example to see why the mathematics is sound.
What a concise way to force a lot of behavior.
--
fred
See Section 3.4.1.
--
Eric Sosman
eso...@ieee-dot-org.invalid
> Implementations have to document something? How general is this
> requirement?
Pretty much exactly as common as the words "implementation defined"
in the standard, with one exception -- that being the description of
the term "implementation defined".
So, if an implementation *doesn't* document how propagation occurs in
the above example, is the behavior just unspecified or does it get
bumped to undefined, as non-entities are?
--
fred
> So, if an implementation *doesn't* document how propagation occurs in
> the above example, is the behavior just unspecified or does it get
> bumped to undefined, as non-entities are?
Neither. In that case, the implementation is broken, and does not conform
to the standard.
If an implementation doesn't document the behavior in a case
where the standard requires it to do so, then the implementation
is non-conforming, and the standard has nothing to say about it
other than that it's non-conforming.
In practice, of course, people aren't typically going to reject an
implementation entirely just because some particular feature isn't
properly documented. The point is that the standard doesn't specify
a fallback position for implementations that fail to conform to it.
--
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"
> >>> An interesting read. Beyond what Ben and Lawrence had to comment, I was
> >>> curious about this language:
>
> >>> > The implementation had to document its choice ....
>
> >>> Implementations have to document something? How general is this
> >>> requirement?
I'm not sure what you mean. Section F.3 of the 1989 ANSI Standard (the
ISO Standard numbers things slightly differently) lists the
implementaion defined behaviours. There are about 14 sub-sections
covering everything from identifier length to the behaviour of the
register directive to various twisty corners of the library.
> >> See Section 3.4.1.
>
> > 3.4.1
> > 1 implementation-defined behavior
> > unspecified behavior where each implementation documents how the
> > choice is made. EXAMPLE An example of implementation-defined behavior
> > is the propagation of the high-order bit when a signed integer is
> > shifted right.
>
> > So, if an implementation *doesn't* document how propagation occurs in
> > the above example, is the behavior just unspecified or does it get
> > bumped to undefined, as non-entities are?
>
> If an implementation doesn't document the behavior in a case
> where the standard requires it to do so, then the implementation
> is non-conforming, and the standard has nothing to say about it
> other than that it's non-conforming.
shoot. So when we asked our compiler supplier to send us the
documentaion and he sent us the ANSI stanbdard instead we didn't have
a conforming implementaion! On the other hand I still have a copy of
the ANSI Standard...
Ok, so is there a list of what a contemporary ISO implementation must
document?
--
fred
Broken? How about imperfect?
--
fred
The standard distinguishes between conforming and non-conforming
implementations. It doesn't distinguish between slightly
non-conforming (imperfect) and badly non-conforming (broken)
implementations.
Of course, you're free to make such a distinction if you like. Seebs
apparently chooses not to do so.
> The standard distinguishes between conforming and non-conforming
> implementations. It doesn't distinguish between slightly
> non-conforming (imperfect) and badly non-conforming (broken)
> implementations.
Ok. That was the lesser of the outstanding questions. The other goes
to the contemporary ISO requirement. If it was annexed in '89, then
there is a well-trodden path to what a conforming-implementation *must*
document.
Right?
--
fred
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf
that's C99 plus technical corrigenda (sp?). So that makes it C05 or
something
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
N1124 incorporates only the first two TCs; N1256 incorporates all
three.
Section 3 of annex J is an explicit list of the things a conforming
implementation must document. The list is gathered from normative
text in other sections of the standard. Annex J itself is
informative, not normative; the list is provided for convenience.
I sure get a lot of mileage out of n1256.pdf.
What does this mean:
J.2 Undefined behavior
1 The behavior is undefined in the following circumstances:
— A ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a
constraint is violated.
(clause 4).
Does gcc support the fortran keyword?
--
fred
When invoked as a C90 or C99 C compiler, no.
Phil
--
I find the easiest thing to do is to k/f myself and just troll away
-- David Melville on r.a.s.f1
It seems clear enough. What part are you having trouble
understanding?
> Does gcc support the fortran keyword?
I don't know. gcc comes with fairly extensive documentation.
Ok.
--
fred
The whole thing. The following is a constraint: "thou shalt not divide
by zero."
Regarding the above constraint, thou shalt keep it.
Doesn't the whole thing seem like Ganto's ax (damned if you do/don't)?
>
>> Does gcc support the fortran keyword?
>
> I don't know. gcc comes with fairly extensive documentation.
>
There is no mention of the fortran keyword in gcc.pdf. I think the
gcc-gfortran projects are so joined at the hip that they get this
behavior out of the filetypes of the source.
--
fred
Constraints are requirements in the standard in paragraphs explicitly
marked "Constraints".
For example, C99 6.5.2.4 says:
6.5.2.4 Postfix increment and decrement operators
Constraints
1 The operand of the postfix increment or decrement operator shall
have qualified or unqualified real or pointer type and shall
be a modifiable lvalue.
Like most constraints, it expresses the requirement using the word
"shall". The expression ``42'' is not a modifiable lvalue. So if you
write:
42 ++;
you've just violated the constraint, and the compiler is required to
issue a diagnostic message.
On the other hand, C99 6.5.6p9 says:
When two pointers are subtracted, both shall point to elements of
the same array object, or one past the last element of the array
object; the result is the difference of the subscripts of the two
array elements.
Again, the requirement is stated using the word "shall", but it's in
the Semantics subsection, not the Constraints subsection. If you write:
int x;
int y;
ptrdiff_t diff = &x - &y;
you've violated the requirement' but you haven't violated a
constraint. (Rationale: compiler cannot in general detect this
particular error, so it can't reasonably be expected to diagnose
it.) This is where J.2 kicks in (actually section 4 paragraph 2).
Your program's behavior is undefined.
> Doesn't the whole thing seem like Ganto's ax (damned if you do/don't)?
Not at all. If you violate such a requirement, your program's
behavior is undefined (and the compiler isn't required to diagnose
the error). If you don't, it isn't.
The "shall" vs. "shall not" just covers two different ways of
expressing a requirement.
>>> Does gcc support the fortran keyword?
>>
>> I don't know. gcc comes with fairly extensive documentation.
>
> There is no mention of the fortran keyword in gcc.pdf.
So there's your answer.
> I think the
> gcc-gfortran projects are so joined at the hip that they get this
> behavior out of the filetypes of the source.
The "fortran" keyword is just one possible mechanism for interfacing
between C and Fortran. As far as I know, it hasn't been widely used
in a very long time.
How could something like 17 / -3 and 17 % -3 produces -5 and -2 or -6
and 1, but something like 17 / 3 and 17 % 3 only produces 5 and 2? Ie,
how come 17 / 3 and 17 % 3 can't produce any other numbers? (Like in
the negative numbers case)
Chad
One of them is ambiguous, the other isn't.
Remainder operations and integer division are unambiguous for positive
integers. For negative integers, it's not clear whether you want to just
reverse the signs of both numbers, or change things so the remainder is
always positive. C99 picked one, C89 left it up to the implementation.
For positive integers, we can say "division rounds down"
or "division discards any fraction" and arrive at the same
result. But if the quotient is negative, "round down" and
"discard fraction" give different results (if the division
isn't exact), hence the ambiguity.
For modulus to match up with division, it has to compensate
for whatever adjustment the division made. The important
property is (a/b)*b + (a%b) == a (provided a/b makes sense).
Since "round down" and "discard fraction" give the same result
for positive quotients, the modulus also gives the same result.
For negative quotients, "round down" needs a compensating
positive modulus, while "discard fraction" needs a negative
adjustment.
--
Eric Sosman
eso...@ieee-dot-org.invalid
Both Fortran and C round toward the origin.
--
fred
C99 rounds toward the origin. C90 rounds toward the
origin *or* toward minus infinity at the implementation's
discretion, as explained earlier in the thread. In both
versions, and with both possible C90 choices, the result
of % "compensates for" whatever rounding / does.
<ot>I don't know Fortran. Long ago I knew FORTRAN and
used it quite a lot, but I've never met the upstart lower-case
pretender to the throne and probably wouldn't recognize it.
<ot>Besides, shouldn't it be ForTran?</ot></ot>
--
Eric Sosman
eso...@ieee-dot-org.invalid