Topic: `long long' (was: Where next for Standard C++?)


Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/10/28
Raw View
kanze@gabi-soft.fr (J. Kanze) writes:

>fjh@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:
>
>|>  kanze@gabi-soft.fr (J. Kanze) writes:
>|>
>|>  >This seems obvious: you don't release code where there is a possibility
>|>  >of overflow.  Period.
>|>
>|>  Tell that to the people who released the Ariane-5 code ;-)
>
>You've picked a bad example.  The Ariane 5 crash is a result of having
>detected overflow.  (In fact, it's more complex than that.)

I don't think it is a bad example.  If the Ariane 5 developers had
followed your advice, the crash would not have occurred.

The developers of Ariane 4 knew that if overflow occurred, then an exception
would be thrown, and that this could cause the system to fail.
However, they knew that the code in question could not overflow.

The problem was that the code was reused for Ariane 5 without rechecking
this assumption.  In fact, for Ariane 5, there was a possibility of
overflow, and when overflow did indeed occur, the system failed.

I think it is a good example because it shows how difficult it
is to ensure that overflow will never occur.  Not only do you have
to get it right in the first place, you need to recheck your assumptions
if the software is reused.  In a large project, this is easy to get wrong,
even if your project is so safety-critical that you take extreme care
and spend very large amounts of money attempting to ensure that your
software won't fail.

>I think what bothers me the most, of course, is that we are punishing (a
>possibly very small minority of) programmers who did the right thing, in
>order to protect the code of those that didn't.  It's the principal of
>the thing.

Ah yes, the moral issue... that is why this debate is so emotive.

The moral principle being applied here is this one:

 The Principle of Reward and Punishment
 --------------------------------------
 People who do the wrong thing deserve to be punished.
 People who do the right thing deserve to be rewarded.
 It is immoral to punish someone for doing the right thing.
 It is immoral to reward someone for doing the wrong thing.

There is another moral principle which could also be applied here, though:

 The Principle of Altruism and Harm Minimization
 -----------------------------------------------
 People who do the wrong thing need help.
 People who do the right thing are usually
 capable of looking after themselves.
 It is immoral to harm those who need help.
 It is a moral imperative to help those who need help.

In this particular case, I find it unlikely that there would be much
deterrent effect from the punishment/reward.  So it seems to me that
for this issue harm minimization is more important.

For a brilliant analysis of moral principles such as these, see George
Lakoff's book "Moral Politics", University of Chicago Press, 1996.
A truly enlightening book, I can't recommend it highly enough.

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: ok@cs.rmit.edu.au (Richard A. O'Keefe)
Date: 1997/10/28
Raw View
ecl6rsh@leeds.ac.uk (R S Haigh) writes:
>I've just read it, but I still don't see the complaint.  Consider
>as a leading example

>void func (size_t size) { printf("%lu\n", (unsigned long)size); }

>If this is used in a working program, the value being passed in
>is presumably the result of some calculation or enquiry.  ...
>If the program works now, then it continues to work, within
>the same spec, if recompiled under C9X.

You've missed the point.  Change the word PROGRAM to the word LIBRARY,
and your conclusions no longer have any basis at all.

--
John Fneas Byron O'Keefe; 1921/02/04-1997/09/27; TLG,TLTA,BBTNOTL.
Richard A. O'Keefe; RMIT Comp.Sci; http://www.cs.rmit.edu.au/%7Eok
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: James Kuyper <kuyper@wizard.net>
Date: 1997/10/28
Raw View
David Chase wrote:
>
> John R MacMillan wrote:
> >
> > |Also, contrary to other posts on the subject, there seems to
> > |be no breaking of strict conformance either.
> >
> > What about the following (admittedly contrived) program, which I
> > believe is strictly conforming C89 and should return EXIT_SUCCESS on
> > all conforming C89 implementations:
>
> I have a hard time getting too excited about this (been programming
> in Java since January, and used "long long" in C for years), but
> if I recall from my C compiler and C debugging environment days,
> strictly conforming programs are few and far between.  Why do
> people think that arguments based on damage to strictly
> conforming C programs are compelling, given that there are
> so few of them?  A cynic might say that only a sucker would
> write a strictly conforming ISO C program, and why do we want
> suckers telling us how to design a language?

Considering the effects on strictly conforming code is a way of
assessing the severity of a change. Almost any change to the standard
will break some code somewhere; if that weren't true, it isn't much of a
change (it might be an addition).
On the other hand, there is subset of all possible programs, called
conforming programs, that are defined to be better behaved than
arbitrarily chosen programs. There is an even smaller set called
strictly conforming programs that is much better behaved.  If a change
is so nasty that it affects even these extremely well-behaved programs,
it is a much more serious change, and should therefore should not be
implemented unless well-motivated.

Strictly conforming programs are a practical impossibility, but doing
the best you can do to write strictly conforming code increases the ease
of porting to new implementations, and to new releases of existing
implementations.

> Or, to put it in other terms, there seems to be a little set
> of "portability rituals" that people programming in C or C++
> must learn in order to achieve either de facto portability,
> or letter-of-the-standard (strict compliance) portability.
> Every language has some quirks, and funny idioms and rituals
> derived from these quirks, but C has more than the other languages
> I know well, and I don't think this is a good thing (*).  People
> who have mastered the techniques of portable programming in C
> may feel proud of their acquired skills, but was this really
> time well spent?  Wouldn't it better to "fix" the language so
> it does not require such skill to do something that ought to
> be easy?

The design of C is a compromise between two goals: portability and
efficiency. Those complicated portability rituals are one of the costs
of the mixed goals. If that compromise is inappropriate for your
application, it might be a good idea to consider a different language,
such as Java for portability, or assembler for efficiency.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/10/29
Raw View
James Kuyper <kuyper@wizard.net> writes:

|>  The design of C is a compromise between two goals: portability and
|>  efficiency.

It's probably worth pointing out that the compromise reflects costs of
20 years ago, and not those of today.  Better optimizing techniques,
etc., mean that better portability could be had a no cost to efficiency.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/10/29
Raw View
fjh@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:

 |> kanze@gabi-soft.fr (J. Kanze) writes:
 |>
 |> >fjh@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:
 |> >
 |> >|>  kanze@gabi-soft.fr (J. Kanze) writes:
 |> >|>
 |> >|>  >This seems obvious: you don't release code where there is a
 |> >|>  >possibility of overflow.  Period.
 |> >|>
 |> >|>  Tell that to the people who released the Ariane-5 code ;-)
 |> >
 |> >You've picked a bad example.  The Ariane 5 crash is a result of having
 |> >detected overflow.  (In fact, it's more complex than that.)
 |>
 |> I don't think it is a bad example.  If the Ariane 5 developers had
 |> followed your advice, the crash would not have occurred.
 |>
 |> The developers of Ariane 4 knew that if overflow occurred, then an
 |> exception would be thrown, and that this could cause the system to fail.
 |> However, they knew that the code in question could not overflow.

They did follow my advice, indirectly.  They checked for overflow (or
counted on built-in checks in the langauge) -- since overflow could not
possibly occur, the handling was treated as a total system failure.

In most cases, this is precisely what I would recommend.  In fact, in
the case of the Ariane, this is precisely what I would recommend.  If
you have a total system failure, the best thing you can do is to blow
the thing up while it is still in the air, rather than risk its coming
down in a densely populated area.

 |> The problem was that the code was reused for Ariane 5 without rechecking
 |> this assumption.  In fact, for Ariane 5, there was a possibility of
 |> overflow, and when overflow did indeed occur, the system failed.

And if you use an Ada compiler to compile your C++ code, you will
probably end up with a message along the lines of "Too many errors,
compilation aborted."  Is this because the authors of the Ada compiler
have been sloppy, and not implemented all of the checks they should
have?

 |> I think it is a good example because it shows how difficult it
 |> is to ensure that overflow will never occur.  Not only do you have
 |> to get it right in the first place, you need to recheck your assumptions
 |> if the software is reused.  In a large project, this is easy to get wrong,
 |> even if your project is so safety-critical that you take extreme care
 |> and spend very large amounts of money attempting to ensure that your
 |> software won't fail.

FWIW: I think the actual authors of the software got it right.  The
behavior was correct for the input data -- for the machine for which it
was written.  Again: don't blame an Ada compiler for not compiling your
C++ code correctly.

   [Fergus: if you want to get in a last word, I won't respond, so that
 the thread -- totally inappropriate in comp.std.c++ -- can die.]

 |> >I think what bothers me the most, of course, is that we are punishing (a
 |> >possibly very small minority of) programmers who did the right thing, in
 |> >order to protect the code of those that didn't.  It's the principal of
 |> >the thing.
 |>
 |> Ah yes, the moral issue... that is why this debate is so emotive.

Well, it's more than just a moral issue.  While cleaning up some code
yesterday, I noticed a very real case in my code which will break if
size_t can be longer than unsigned long.  Now the C committee have given
me another solution, but it won't work in current compilers.  Which
means that until all compilers implement the new standard, there is NO
portable solution, what so ever.

 |> The moral principle being applied here is this one:
 |>
 |>  The Principle of Reward and Punishment
 |>  --------------------------------------
 |>  People who do the wrong thing deserve to be punished.
 |>  People who do the right thing deserve to be rewarded.
 |>  It is immoral to punish someone for doing the right thing.
 |>  It is immoral to reward someone for doing the wrong thing.
 |>
 |> There is another moral principle which could also be applied here, though:
 |>
 |>  The Principle of Altruism and Harm Minimization
 |>  -----------------------------------------------
 |>  People who do the wrong thing need help.
 |>  People who do the right thing are usually
 |>  capable of looking after themselves.
 |>  It is immoral to harm those who need help.
 |>  It is a moral imperative to help those who need help.
 |>
 |> In this particular case, I find it unlikely that there would be much
 |> deterrent effect from the punishment/reward.  So it seems to me that
 |> for this issue harm minimization is more important.

I'm all in favor of harm minimization.  Above all, of course, when it
applies to myself.  In this case, the current proposal causes me a
significant amount of grief.  (Moral grief, at least.  I seriously doubt
that the program will fail in the future, despite the change.  But I can
no longer prove it -- there are potentially user values for which it
will fail, even if it is highly unlikely that the user will provide such
values.)

 |> For a brilliant analysis of moral principles such as these, see George
 |> Lakoff's book "Moral Politics", University of Chicago Press, 1996.
 |> A truly enlightening book, I can't recommend it highly enough.

As if I weren't already far enough behind in my reading.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: john@mail.interlog.com (John R MacMillan)
Date: 1997/10/27
Raw View
|Also, contrary to other posts on the subject, there seems to
|be no breaking of strict conformance either.

What about the following (admittedly contrived) program, which I
believe is strictly conforming C89 and should return EXIT_SUCCESS on
all conforming C89 implementations:

#include <stddef.h>
#include <stdlib.h>

int main()
{
 size_t v1 = (size_t)-1;
 unsigned long v2 = (size_t)-1;

 return (v1 == v2) ? EXIT_SUCCESS : EXIT_FAILURE;
}

Under C9X, this is no longer strictly conforming (not directly
because of long long, but because of the types-longer-than-long of
which long long is an example), so there is breaking of strict
conformance.
--
To reply by mail, please remove "mail." from my address -- but please
send e-mail or post, not both
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/10/28
Raw View
fjh@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:

|>  kanze@gabi-soft.fr (J. Kanze) writes:
|>
|>  >fjh@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:
|>  >
|>  >|>  My question to the people who are so worried about code like the above
|>  >|>  breaking is this: do you check every addition and multiplication
|>  >|>  for overflow, in cases were it might possibly overflow?  No?
|>  >|>  Then your code isn't strictly conforming anyway.
|>  >
|>  >This seems obvious: you don't release code where there is a possibility
|>  >of overflow.  Period.
|>
|>  Tell that to the people who released the Ariane-5 code ;-)

You've picked a bad example.  The Ariane 5 crash is a result of having
detected overflow.  (In fact, it's more complex than that.)

|>  Oh yes, and tell that to all the people who released code that
|>  is going to break in the year 2000...
|>
|>  James, I find your attitude admirable, but it just doesn't
|>  reflect what I see happening in the real world.

I think it's improving.  While I suspect (or fear) that you are right
with regards to the total amount of existing software, my impression is
that more and more programmers are doing the right thing.  Another
poster mentioned emacs, INN and a couple of other programs as maybe
doing the right thing.

I think what bothers me the most, of course, is that we are punishing (a
possibly very small minority of) programmers who did the right thing, in
order to protect the code of those that didn't.  It's the principal of
the thing.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: David Chase <chase@world.std.com>
Date: 1997/10/28
Raw View
John R MacMillan wrote:
>
> |Also, contrary to other posts on the subject, there seems to
> |be no breaking of strict conformance either.
>
> What about the following (admittedly contrived) program, which I
> believe is strictly conforming C89 and should return EXIT_SUCCESS on
> all conforming C89 implementations:

I have a hard time getting too excited about this (been programming
in Java since January, and used "long long" in C for years), but
if I recall from my C compiler and C debugging environment days,
strictly conforming programs are few and far between.  Why do
people think that arguments based on damage to strictly
conforming C programs are compelling, given that there are
so few of them?  A cynic might say that only a sucker would
write a strictly conforming ISO C program, and why do we want
suckers telling us how to design a language?

Or, to put it in other terms, there seems to be a little set
of "portability rituals" that people programming in C or C++
must learn in order to achieve either de facto portability,
or letter-of-the-standard (strict compliance) portability.
Every language has some quirks, and funny idioms and rituals
derived from these quirks, but C has more than the other languages
I know well, and I don't think this is a good thing (*).  People
who have mastered the techniques of portable programming in C
may feel proud of their acquired skills, but was this really
time well spent?  Wouldn't it better to "fix" the language so
it does not require such skill to do something that ought to
be easy?

(*) any argument based on an inability to distinguish small
non-zero numbers from arbitrarily large numbers is uninteresting.
My children know the difference between one spoonful of spinach
and ten, but a small non-zero number of people posting to the
net apparently do not.

I think it would be a good thing in any future standard if it were
a little bit easier to write a strictly-conforming program, so that
there would be more of them.  This means that well-defined integer
types need to exist, and there need to be well-defined division
and remainder operations, and signed and unsigned integers should
have well-defined conversion and casting operations (for example,
when casting an integer x of type __intXX to an unsigned of
type __uintXX, if x is less than zero, the unsigned result is
numerically equal to "2-to-the-XX plus x").

--
David Chase, chase@world.std.com
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/10/24
Raw View
fjh@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:

|>  My question to the people who are so worried about code like the above
|>  breaking is this: do you check every addition and multiplication
|>  for overflow, in cases were it might possibly overflow?  No?
|>  Then your code isn't strictly conforming anyway.

This seems obvious: you don't release code where there is a possibility
of overflow.  Period.  You don't check every operation, but you do
validate all input values, and use value induction to prove that
overflow can't occur.  (And yes, it sometimes means formulating
expressions in strange ways, to ensure that signed integer arithmetic
won't generate illegal intermediate values, even though you know that on
99.9% of all implementations, the final results will be correct anyway.
It's just a question of being professional.)

|>  Consider the hypothetical system with 64 bit pointers and 32 bit long.
|>  For the code above to fail, you must somehow have computed a value
|>  of type `size_t' which doesn't fit in 32 bits, which you then pass to
|>  func().  But if you have done that, then (unless you are very careful
|>  about checking for overflow, and I've never seen C code that is)
|>  your program would fail anyway, if the implementation had 32 bit size_t.

No.  Because at some point in entry, you have compared values with a
value derived from (size_t)( -1 ).  This is pretty much standard
procedure, and I can't imagine anyone releasing a program without having
done it.

|>  So although the complaint is that C9X will break strictly conforming C89
|>  constructs, when you look at real programs it seems to me that the
|>  actuality is this: for programs which were not strictly conforming to C89,
|>  and which didn't work on some hypothetical implementations which don't
|>  yet exist, with C9X these programs will now not work on some different
|>  hypothetical implementations which also don't yet exist.
|>  To me, this does not seem worth getting so fussed up about!
|>
|>  >(it might still accidentally work for values that fit in 32 bits,
|>  >depending upon the endianess).
|>
|>  No, for values that fit in 32 bits, it will continue to work regardless
|>  of endianness.

This is actually the worst aspect of it.  It is necessary to modify
existing code.  OK, that's progress.  But the change is silent -- the
compiler will not tell me what has to be modified.  So there is a non-0
risk that something gets missed.  Of course, like any serious
programmer, I will run regression tests after the modification.  Now:
you tell me what is the probability of my regression test catching the
error.  The result is that the change generates errors which will only
appear in the field, much later.

|>  >The
|>  >same difficulty applies to any other integer-valued standard typedef.
|>  >Automated searches for cases affected by this problem is very difficult,
|>  >bordering on impossible, rendering conversion of large projects to C9x
|>  >significantly more difficult than it would otherwise need to be.
|>
|>  Automated searches for cases affected by this problem are not
|>  "bordering on impossible", they are quite achievable with current
|>  technology.  All you need to do is compile your code on a system
|>  which has `long long' size_t (or perhaps just using header files
|>  modified for this purpose), and use a compiler that warns about
|>  conversions from `long long' to `long'.  Such warnings are very
|>  easy for a compiler writer to implement.
|>
|>  Now it is true that not everyone has such a compiler.
|>  However, if you want to convert a large program to C9X,
|>  and you don't have such a compiler, there is a simple solution:
|>  just add `assert(sizeof(size_t) <= sizeof(long))' or equivalent
|>  at the start of main().  Your program will be no less portable
|>  than it was before.  And when the time comes to port to a system
|>  which violates that assertion, the compiler for that system
|>  will no doubt offer such warnings, if there is any demand for it.

Finally, something I can agree with:-).  I just hope compiler
implementers are listening.  (There is a long tradition in C/C++ that a
compiler NEVER generate a warning when there is an explicit cast.  An
explicit cast says that the programmer knows what he is doing.  In this
case, he knew what he was doing when he wrote the code, but someone
changed the deck.)

|>  >There is also a parsing problem, about which I know very little, caused
|>  >by the fact that 'long long' is the only type whose recognition requires
|>  >a count of duplicate tokens.
|>
|>  This problem is insignificant.  Parsing `long long' is trivial.

I don't know about trivial, but solved, anyway:-).  The main (only?)
argument for "long long" is existing practice.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: ecl6rsh@leeds.ac.uk (R S Haigh)
Date: 1997/10/24
Raw View
In article <62oc8e$jd$1@shade.twinsun.com>, eggert@twinsun.com (Paul Eggert) writes:
> fjh@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:

> The problem isn't a matter of strict conformance.
> It's a matter of practical programs:
> programs that used to work assuming `long' was the longest integer type;
> programs that stop working once this is no longer true.
> If this were merely a theoretical issue, people wouldn't care so much.

> For more details about this problem, please see
> <news:5rqqgb$6je$1@shade.twinsun.com> (1997-07-31).
> You can fetch that article from Dejanews's Old database using the query
> `Apache, Bash, CVS, Emacs, INN, Pine, Tcl, and X11R6'.

I've just read it, but I still don't see the complaint.  Consider
as a leading example

void func (size_t size) { printf("%lu\n", (unsigned long)size); }

If this is used in a working program, the value being passed in
is presumably the result of some calculation or enquiry.  That
value is converted to a size_t and then to an unsigned long.  If
it doesn't survive these conversions without a wrap-around, the
program is already broken, or at least, it's being used outside its
spec.  If the program works now, then it continues to work, within
the same spec, if recompiled under C9X.

Of course, if you upgrade your hardware and/or OS, some system
space enquiry might now yield a value that's too long for the program.
But now, the program is being used outside its spec: it wasn't designed
for numbers this big.  However, you can't say the program has
"stopped working", because it never did work on this new system.

In this situation, the program needs a port/upgrade.  This is normal.
The code may have been portable across some given set of systems,
but nobody said it was parametrised against future developments.
Not much software written for 16/32-bit platforms faces the possibility
of having to cope with integers that won't fit into 32 bits, but
that's not the fault of the C type system; it's just that
future-proofing wasn't a development priority.  C9X standardises
the means of doing the upgrade: you can't expect it to make the
upgrade automatic.


Also, contrary to other posts on the subject, there seems to
be no breaking of strict conformance either.  Strict conformance
as defined applies to programs, not functions.  The above function
can only be called in a strictly conforming program if the value
passed is within the legal minimum range of a size_t, and in that
case the program continues to be strictly conforming.  I imagine
it would be possible to develop a notion of strict conformance for
library code by placing numerical limits on the values of arguments,
but the same conclusion follows.

--
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/24
Raw View
R S Haigh wrote:

[long long breaks programs.]

> Also, contrary to other posts on the subject, there seems to
> be no breaking of strict conformance either.

Of course there is !

> Strict conformance
> as defined applies to programs, not functions.  The above function
> can only be called in a strictly conforming program if the value
> passed is within the legal minimum range of a size_t, and in that
> case the program continues to be strictly conforming.

I don't see how you came to this conclusion.

> I imagine
> it would be possible to develop a notion of strict conformance for
> library code by placing numerical limits on the values of arguments,
> but the same conclusion follows.

Passing _any_ value which fit in size_t to a function taking a size_t
is strictly conforming. In particular, passing any sizeof (something),
any size_t returned by a library function, or ((size_t)-1). There is
no reasons for these values to fit in some prefefined range.

Actually the ONLY reason for having size_t (except self documentation)
is that you are wrong.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: ecl6rsh@leeds.ac.uk (R S Haigh)
Date: 1997/10/26
Raw View
In article <3450D609.2D67@pratique.fr>, Valentin Bonnard <bonnardv@pratique.fr> writes:

> Passing _any_ value which fit in size_t to a function taking a size_t
> is strictly conforming. In particular, passing any sizeof (something),
> any size_t returned by a library function, or ((size_t)-1). There is
> no reasons for these values to fit in some prefefined range.

Maybe it's different in C++.  But in C, a program isn't strictly
conforming if its output depends on anything that's implementation-defined.
And the value at which size_t wraps round is implementation-defined,
so if you exceed the legal minimum and the effect is observable in
the output, the program isn't strictly conforming.

Putting it another way, if you expect the output of a program to
vary between implementations (and printfing (size_t)-1 obviously will),
there is no way the program can be strictly conforming no matter how
you write it.  The first prerequisite for a strictly conforming
program is that the description of its observable behaviour isn't a
function of the implementation.

No I don't like it either -- if the use of "implementation defined"
were subject to more useful criteria (from the point of view of
portability) then I believe the definition of "strictly conforming"
could be usefully relaxed.  At present it only covers a small
subset of the programs that a conforming compiler is required (by
other wording) to do the right thing with (which might be seen as
a more general concept of "maximally portable").


> Actually the ONLY reason for having size_t (except self documentation)
> is that you are wrong.

As for why size_t exists, I've been wondering about that.  I see
three possibilities:

1) nothing to do with future-proofing, in which case the existing
guarantees should be retained

2) for future-proofing, with the intention that it should always
be not wider than unsigned long.  That can't have been the intent,
since (a) it would have pre-empted the whole 64-bit issue, and
(b) a new type name would have been superfluous

3) for future-proofing, with the intent that it may get wider
than unsigned long.  A more plausible idea, but it does take
more than a typedef.  A portable and future-proof printf specifier,
or at least a portable macro kludge, is needed to get this kind
of scheme very far off the ground.

I don't claim that the situation isn't a mess; but the problems
are inherent in C89 and not affected by anything since.  The
facilities for portably future-proofing code are incomplete,
making the need to modify source for 64-bit inevitable.  Widening
long wouldn't have changed that: it would have changed the
details of updating code, but not the need to do it.

--
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: pcurran@acm.gov (Peter Curran)
Date: 1997/10/26
Raw View
On 23 Oct 97 18:25:40 GMT in article <62o48f$as2@mulga.cs.mu.OZ.AU>
    fjh@mundook.cs.mu.OZ.AU (Fergus Henderson) (Fergus Henderson) wrote:

<snip>
 >Consider the hypothetical system with 64 bit pointers and 32 bit long.
 >For the code above to fail, you must somehow have computed a value
 >of type `size_t' which doesn't fit in 32 bits, which you then pass to
 >func().  But if you have done that, then (unless you are very careful
 >about checking for overflow, and I've never seen C code that is)
 >your program would fail anyway, if the implementation had 32 bit size_t.
 >
 >So although the complaint is that C9X will break strictly conforming C89
 >constructs, when you look at real programs it seems to me that the
 >actuality is this: for programs which were not strictly conforming to C89,
 >and which didn't work on some hypothetical implementations which don't
 >yet exist, with C9X these programs will now not work on some different
 >hypothetical implementations which also don't yet exist.
 >To me, this does not seem worth getting so fussed up about!
<snip>

There are more uses of values, Horatio, than are dreamt of in your philosophy.

--
Peter Curran                                pcurran@acm.gov
                      (change gov to org for actual address)
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/10/23
Raw View
James Kuyper <kuyper@wizard.net> writes:

>The key question is whether code like the following is still guaranteed to
>work:
>
>void func(size_t s)
>{
> printf("size:%ul\n", (unsigned long)s);
>}
>
>That code was guaranteed to work as intended by the C89 standard. Under
>the proposed C9x standard, that code would need to be modified to use
>the new features in the <inttypes.h> header file. Without such
>modifications, it may fail on any system that implements, for instance,
>64 bit pointers and 32 bit unsigned long's

Only if such a system has 64 bit size_t.
If such a system has 32 bit size_t, then the above code won't fail.
A conforming implementation may have 64 bit pointers but 32 bit size_t.

My question to the people who are so worried about code like the above
breaking is this: do you check every addition and multiplication
for overflow, in cases were it might possibly overflow?  No?
Then your code isn't strictly conforming anyway.

Consider the hypothetical system with 64 bit pointers and 32 bit long.
For the code above to fail, you must somehow have computed a value
of type `size_t' which doesn't fit in 32 bits, which you then pass to
func().  But if you have done that, then (unless you are very careful
about checking for overflow, and I've never seen C code that is)
your program would fail anyway, if the implementation had 32 bit size_t.

So although the complaint is that C9X will break strictly conforming C89
constructs, when you look at real programs it seems to me that the
actuality is this: for programs which were not strictly conforming to C89,
and which didn't work on some hypothetical implementations which don't
yet exist, with C9X these programs will now not work on some different
hypothetical implementations which also don't yet exist.
To me, this does not seem worth getting so fussed up about!

>(it might still accidentally work for values that fit in 32 bits,
>depending upon the endianess).

No, for values that fit in 32 bits, it will continue to work regardless
of endianness.

>The
>same difficulty applies to any other integer-valued standard typedef.
>Automated searches for cases affected by this problem is very difficult,
>bordering on impossible, rendering conversion of large projects to C9x
>significantly more difficult than it would otherwise need to be.

Automated searches for cases affected by this problem are not
"bordering on impossible", they are quite achievable with current
technology.  All you need to do is compile your code on a system
which has `long long' size_t (or perhaps just using header files
modified for this purpose), and use a compiler that warns about
conversions from `long long' to `long'.  Such warnings are very
easy for a compiler writer to implement.

Now it is true that not everyone has such a compiler.
However, if you want to convert a large program to C9X,
and you don't have such a compiler, there is a simple solution:
just add `assert(sizeof(size_t) <= sizeof(long))' or equivalent
at the start of main().  Your program will be no less portable
than it was before.  And when the time comes to port to a system
which violates that assertion, the compiler for that system
will no doubt offer such warnings, if there is any demand for it.

>There is also a parsing problem, about which I know very little, caused
>by the fact that 'long long' is the only type whose recognition requires
>a count of duplicate tokens.

This problem is insignificant.  Parsing `long long' is trivial.

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: eggert@twinsun.com (Paul Eggert)
Date: 1997/10/24
Raw View
fjh@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:

>do you check every addition and multiplication
>for overflow, in cases were it might possibly overflow?  No?
>Then your code isn't strictly conforming anyway.

The problem isn't a matter of strict conformance.
It's a matter of practical programs:
programs that used to work assuming `long' was the longest integer type;
programs that stop working once this is no longer true.
If this were merely a theoretical issue, people wouldn't care so much.

> unless you are very careful
> about checking for overflow, and I've never seen C code that is

If you'd like to see an example of C code that _is_ careful about overflow,
please take a look at the mktime.c shipped with GNU Emacs 20.
If you can find a bug in it due to overflow on a real host, I'd like to
hear about it!  Unfortunately, that program breaks if you compile it
with -DDEBUG and if time_t is longer than `long'.  Luckily, no hosts
that I know of have _that_ particular bit of brain damage (though C9X
will allow it), so it's not worth coding around.

It's not merely a matter of checking for overflow.
It's also a matter of printing numbers.  That's why lots of
real programs can stop working if types longer than `long'
are used by the system.  These programs include
Apache, Bash, CVS, Emacs, INN, Pine, Tcl, and X11R6.

For more details about this problem, please see
<news:5rqqgb$6je$1@shade.twinsun.com> (1997-07-31).
You can fetch that article from Dejanews's Old database using the query
`Apache, Bash, CVS, Emacs, INN, Pine, Tcl, and X11R6'.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: James Kuyper <kuyper@wizard.net>
Date: 1997/10/24
Raw View
[My apologies to comp.std.c readers, who have seen this issue thoroughly
discussed many times before. The question came up in comp.std.c++ about
whether 'long long' should be added to the next version of the C++
standard, for compatibility with C9X.]

Fergus Henderson wrote:
>
> James Kuyper <kuyper@wizard.net> writes:
...
> >void func(size_t s)
> >{
> >       printf("size:%ul\n", (unsigned long)s);
> >}
> >
> >That code was guaranteed to work as intended by the C89 standard. Under
> >the proposed C9x standard, that code would need to be modified to use
> >the new features in the <inttypes.h> header file. Without such
> >modifications, it may fail on any system that implements, for instance,
> >64 bit pointers and 32 bit unsigned long's
>
> Only if such a system has 64 bit size_t.
> If such a system has 32 bit size_t, then the above code won't fail.
> A conforming implementation may have 64 bit pointers but 32 bit size_t.

Yes, that's one reason why I said 'may fail', rather than 'will fail'.

...
> Consider the hypothetical system with 64 bit pointers and 32 bit long.
> For the code above to fail, you must somehow have computed a value
> of type `size_t' which doesn't fit in 32 bits, which you then pass to
> func().  But if you have done that, then (unless you are very careful
> about checking for overflow, and I've never seen C code that is)
> your program would fail anyway, if the implementation had 32 bit size_t.

I guess I should have made my example more specific. The statement

 printf("sizeof(object)=%ul\n", (unsigned long)sizeof(object));

was guaranteed to work correctly under C89 (assuming that 'object' was a
valid object name), without any need for me to check for overflow. The
need exists only in C9X. Note that 'object' might be bigger in the 64
bit implementation than in the 32 bit implementation, even without any
change in its definition; it could contain implementation dependent
padding, a fundamental type with an implementation dependent size, an
implementation dependent typedef, or use an implementation dependent
macro as a subscript.

Similar "guaranteed safe" expressions exist for each of the other
integral-type standard typedefs. Those expressions were guaranteed to
safely convert to 'long' or 'unsigned long', as appropriate, under C89;
that won't be true under C9X.

> >Automated searches for cases affected by this problem is very difficult,
> >bordering on impossible, rendering conversion of large projects to C9x
> >significantly more difficult than it would otherwise need to be.
>
> Automated searches for cases affected by this problem are not
> "bordering on impossible", they are quite achievable with current
> technology.  All you need to do is compile your code on a system
> which has `long long' size_t (or perhaps just using header files
> modified for this purpose), and use a compiler that warns about
> conversions from `long long' to `long'.  Such warnings are very
> easy for a compiler writer to implement.

Most good compilers will warn about dangerous implicit conversions if
you set the appropriate options. The SGI compiler I'm using now has a
-wlint mode, in which it complains about all implicit conversions,
whether or not they're safe, which isn't quite as useful. Unfortunately,
-wlint mode isn't available for the 64 bit ABI.
However, I've never used a compiler that issued warning messages about
valid explicit casts. If it did, I would end up being swamped by
messages from all the legitimate places I use them; the ones that were
truly dangerous would be lost in the jumble.

You can't get around this problem by having the compiler flag only
potentially dangerous casts; explicit casts are usually ones that a
compiler might incorrectly flag as potentially unsafe. It's the
programmer's responsibility, not the compiler's, for determining whether
an explicit cast is safe. The explicit cast used above was guaranteed
perfectly safe under C89, and it won't be under C9X.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/10/24
Raw View
kanze@gabi-soft.fr (J. Kanze) writes:

>fjh@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:
>
>|>  My question to the people who are so worried about code like the above
>|>  breaking is this: do you check every addition and multiplication
>|>  for overflow, in cases were it might possibly overflow?  No?
>|>  Then your code isn't strictly conforming anyway.
>
>This seems obvious: you don't release code where there is a possibility
>of overflow.  Period.

Tell that to the people who released the Ariane-5 code ;-)

Oh yes, and tell that to all the people who released code that
is going to break in the year 2000...

James, I find your attitude admirable, but it just doesn't
reflect what I see happening in the real world.

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]