Re: Discussion about why GNU/Linux system upgrades cause old programs to break

Arsen Arsenović <[email protected]>
Newsgroups gmane.emacs.devel
Message-ID <[email protected]>
Richard Stallman <[email protected]> writes:

>   > >
>   > > Even if we agree that that particular deviation had become a bad idea
>   > > to use, reporting it as an error and making compilation fail is harsh,
>   > > and causes trouble for the users of GCC.
>
>   > For this particular deviation, not reporting it as an error or not
>   > making compilation fail also causes trouble for the users of GCC.
>
> Are you and I talking about the same set of cases?

Presumably - I mean the cases permitted by -fpermissive as of GCC 14,
that were previously permitted by default.

> Are you saying it causes trouble _for some programs on some possible
> platforms_, or _that it causes trouble for all such programs on
> whichever platform that user uses_?

The latter.

Though, whether the problem manifests noticeably depends on other
factors.

They're /very/ likely to manifest noticeably on many platforms, however.
The examples given before all happen on x86_64 and aarch64 (and
presumably also rv64).  One of the examples given below manifests on all
platforms.

>   > The users have already changed that code.  The vast, vast, majority of
>   > cases where these diagnostics are emitted are not intentional uses but,
>   > rather, indicative of a bug.
>
> I think it would be useful to clarify what "bug" means in that statement.
>
> Does it mean, "on some possible standard-conforming platform, the
> program would execute wrong"?
>
> Does it mean, "the program will execute wrong on a platform that
> user will use in the next year or next decade"?

In this particular case, the latter is closer.

Again, as an example, it's enough for a pointer to be used as a return
value on a 64-bit platforms, which are not at all uncommon, or for a
'long long' to be used as a return value on any platform, for *visible*
breakage when such a function is called through an implicit function
declaration even in the most forgiving of conditions.

Note that this is a lone example in which it is almost guaranteed to
manifest as a problem; in practice there are other ways for other bugs
to manifest.

But, note that even if something does not manifest as, or perhaps even
is not at all a bug (e.g. call to an implicitly-declared function whose
implicit declaration matches its definition), most GCC users still did
not intend it.  Very few people intend to rely on implicit function
declarations or unprototyped functions, as those mean that the type
checker is doing far less work on their project than they'd like it to,
and thus they're relying on type checking that isn't happening to keep
notify them about incorrect use.

However, to broaden this beyond just this one particular change and this
one particular example, as I've explained before, programs that make
false assumptions aren't only broken on "some possible standard
conforming platform", they can - and often will - also break with newer
compiler releases, or older compiler releases, or when the user chooses
to perform link-time optimization instead of not performing it, or when
the user chooses no to perform LTO instead of performing it, or when the
user uses -O3 instead of -O2, or if the user uses -O1 instead of -O2, or
when the users CPU supports an instruction that the developers' CPU
doesn't, or when the users CPU lacks an instruction that the developers'
CPU has, or when the stack size used by the user is different to that
used by the developer, or when the heap address on the users' end
differs to that used by the developer, ....

Just because a program happened to work in one configuration (where
configuration is understood to mean a total description of the entire
system; the particular CPU, compiler, OS, library versions, flags used
to build the compiler, OS, libraries, and the final program, ...) does
not mean that it will work in any other, even if very similar.

The only way to guarantee a program works in all configurations is not
to make such false assumptions.

And there's no way to "fix" that.

How could there be?

The compiler can't mind-read to provide guarantees that the developer
imagined that have no basis either in the language itself or in the
extensions to the language.

Please do not imagine such guarantees.

Note that this is distinct from implementation-defined behaviour,
obviously those can be relied upon *if the implementation guarantees
them* even if the base language does not, presuming that you document
what implementation is to be used.  (IME, though, this is more trouble
than it's worth most of the time as it makes it far harder to get
programs running on other platforms, but it /is/ a valid thing to do.)

Note also that this is not the same as writing portable code.

You can write code that will only ever run on one CPU and one libc and
one kernel with no other dependencies, and it will still break
eventually if it contains such false assumptions.

This can be done by, for instance, using inline-asm or some CPU-specific
libc extension, while returning a 'long long' from a function called
through an implicit function declaration.  This is completely
unportable, and yet will produce wrong execution.

On the other hand, you can write a program for a given Unix-like system
which makes no false assumptions and breaks no preconditions the
language requires, and it still won't run on e.g. Windows, probably
because you included some completely valid, specified, and documented
header and called some completely valid, specified, and documented
function in the way that is documented from that header, but it only
exists for that system, and not for Windows, or even other similar
systems.

For instance, you could call reallocarray; doing so is completely valid
and perfectly fine but that program will no longer be able to run on
Windows or even on some Unix-like systems, despite making no false
assumptions.

But, calling it through a mismatched declaration (e.g. the implicitly
generated one) will result in strange bugs even on those systems that
provide it.

Not violating the rules of the language helps with portability, sure,
but it is not the same thing as portability.  Foregoing portability does
not mean foregoing the rules of the language you're using.

Even if I don't particularly care whether or not my programs runs on
SPARC, and don't test on it, this does *not* mean that I'm permitted to
assume accesses to misaligned pointers are permitted just because 'ld'
or 'mov' on the CPUs I /do/ test for permit unaligned accesses.

They aren't.

If I was to, based on that instruction selection, assume that I can
perform unaligned accesses, this may break: a future compiler version
may choose an instruction other than 'ld' or 'mov', which does require a
higher degree of alignment.

And the ensuing breakage is my fault, because I made a false assumption.

I already went over why in an earlier reply.
-- 
Arsen Arsenović
signature.asc (application/pgp-signature, 418 B)
-----BEGIN PGP SIGNATURE-----

iQECBAEWCgCqFiEE/uKz0RP8AKMWLWBhUsKUMB6ixJMFAmqMZZ8bFIAAAAAABAAO
bWFudTIsMi41KzEuMTIsMiwyXxSAAAAAAC4AKGlzc3Vlci1mcHJAbm90YXRpb25z
Lm9wZW5wZ3AuZmlmdGhob3JzZW1hbi5uZXRGRUUyQjNEMTEzRkMwMEEzMTYyRDYw
NjE1MkMyOTQzMDFFQTJDNDkzEBxhcnNlbkBhYXJzZW4ubWUACgkQUsKUMB6ixJPp
AAD9FvArfgfiHOEkEmIVb0ZC+L+QDF5Bn/EZTuC2PFaAou0BALDBDsMjNkZGtrOE
99ICj1/z3YP0COrEYpP2U9QckvcA
=qI6i
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.