Re: Discussion about why GNU/Linux system upgrades cause old programs to break
Arsen Arsenović <[email protected]> Tue, 11 Aug 2026 19:48:08 +0200
| Newsgroups | gmane.emacs.devel |
|---|---|
| Message-ID | <[email protected]> |
Eli Zaretskii <[email protected]> writes: >> > What happened was a system upgrade. I don't expect a system upgrade >> > to remove capabilities. Am I alone in this expectation? >> >> An upgrade can most certainly do that: if A version 1 requires B and C, >> and A version 2 requires merely B, the upgrade and and subsequent >> cleanup will remove C. > > What is A in this case? Any package managed by the OS (and its package manager), and B and C are any packages managed by the OS that A depends upon. A concrete example: A=PCmanFM (a GUI file manager), which can be built against B=GTK, either 2 or 3, and lets assume it depends on C=libattr. Let us suppose that, in one release of Trisquel, it was built against GTK2, and in the next, GTK3, and that nothing else using GTK2 was installed. Then, upgrading Trisquel means GTK2 becomes unneeded. Thus, after the admin runs 'apt autoremove', it goes away. libattr happens to stay. Obviously, I don't know whether that's what happened on Fencepost, but I hope that putting in concrete package names makes it easier to follow. > If that's Emacs, then Emacs was not upgraded, only the OS was. Your copy of Emacs isn't managed by the package manager. It does not (and indeed can't really) know about that Emacs. > And at least in my book, upgrading should not remove old libraries > except when they are replaced with newer ones that are ABI-compatible. Yes, usually package managers only remove packages on upgrade in case of such conflicts. > Otherwise, old programs built by users will break. > > Alternatively, a program should be built in a way that it links to a > generic libFOO.so, not to a version-specific libFOO-nn.so.0, so that > upgrading will redirect the generic link to the actual library, and > programs will still work (provided that the new library is > ABI-compatible with the old one). There's no generic GTK. GTK 2, 3 and 4 are mutually incompatible. In general, programs are linked to as generic a variant as possible. In the examples you presented, the generic variants were GTK 2 and 3. > And if libpng12.so is just an image library and probably comes from > some add-on package, some of the libraries which broke old Emacsen are > not in that category: > > emacs-24.x/emacs-24.1/src/emacs: error while loading shared libraries: libgtk-x11-2.0.so.0: cannot open shared object file: No such file or directory > > This library seems to be part of GTK and/or X11, which makes it a > "system library" in my book. This is GTK2. Same story goes: the admin removed GTK2, whether accidentally or intentionally, I can't say. Generally, package managers don't really consider anything a "system package". (What would that be? Everyone needs different things. My server doesn't need GTK) What actually happens is that the distro comes preinstalled with a "meta package" (an empty package used only for its metadata) that depends on whatever the system ought to have preinstalled. Debian calls these "tasks". I presume the same goes for its derivatives. Though I'm not too familiar in either Debian or its derivatives. If the package manager has a concept of system packages (e.g. Gentoo's @system), it is usually the set of packages expected to be present by all other programs. For instance, the Gentoo @system set for a KDE Plasma and systemd desktop profile contains: ~$ equery l @system * Searching for @system ... [IP-] [ ] app-admin/eselect-1.4.32:0 [IP-] [ ] app-alternatives/awk-4:0 [IP-] [ ] app-alternatives/bzip2-1:0 [IP-] [ ] app-alternatives/gzip-1:0 [IP-] [ ] app-alternatives/sh-0:0 [IP-] [ ] app-alternatives/tar-0:0 [IP-] [ ] app-arch/bzip2-1.0.8-r5:0/1 [IP-] [ ] app-arch/gzip-1.14:0 [IP-] [ ] app-arch/tar-1.35-r1:0 [IP-] [ ] app-arch/xz-utils-5.8.3:0 [IP-] [ ] app-shells/bash-5.3_p15:0 [IP-] [ ] dev-build/make-4.4.1-r102:0 [IP-] [ ] net-mail/mailbase-1.8.1:0 [IP-] [ ] net-misc/iputils-20250605-r4:0 [IP-] [ ] net-misc/rsync-3.4.4:0 [IP-] [ ] net-misc/wget-1.25.0-r2:0 [IP-] [ ] sec-keys/openpgp-keys-gentoo-release-20260125:0 [IP-] [ ] sys-apps/baselayout-2.18-r1:0 [IP-] [ ] sys-apps/coreutils-9.11-r1:0 [IP-] [ ] sys-apps/diffutils-3.12:0 [IP-] [ ] sys-apps/file-5.48:0 [IP-] [ ] sys-apps/findutils-4.11.0:0 [IP-] [ ] sys-apps/gawk-5.4.1:0 [IP-] [ ] sys-apps/grep-3.12:0 [IP-] [ ] sys-apps/iproute2-7.0.0:0 [IP-] [ ] sys-apps/kbd-2.10.0:0 [IP-] [ ] sys-apps/kmod-34.2:0 [IP-] [ ] sys-apps/less-704:0 [IP-] [ ] sys-apps/man-pages-6.17-r1:0 [IP-] [ ] sys-apps/net-tools-2.10:0 [IP-] [ ] sys-apps/sed-4.10-r1:0 [IP-] [ ] sys-apps/shadow-4.20.0:0/6 [IP-] [ ] sys-apps/util-linux-2.42.2:0 [IP-] [ ] sys-apps/which-2.23:0 [IP-] [ ] sys-devel/binutils-2.46.1:2.46 [IP-] [ ] sys-devel/binutils-2.47:2.47 [IP-] [ ] sys-devel/gcc-15.3.1_p20260717:15 [IP-] [ ] sys-devel/gcc-16.2.0:16 [IP-] [ ] sys-devel/gnuconfig-20260517:0 [IP-] [ ] sys-devel/patch-2.8-r1:0 [IP-] [ ] sys-fs/e2fsprogs-1.47.4:0 [IP-] [ ] sys-process/procps-4.0.6:0/1-ng [IP-] [ ] sys-process/psmisc-23.7:0 [IP-] [ ] virtual/dev-manager-0-r2:0 [IP-] [ ] virtual/editor-0-r7:0 [IP-] [ ] virtual/libc-1-r1:0 [IP-] [ ] virtual/man-0-r4:0 [IP-] [ ] virtual/os-headers-0-r2:0 [IP-] [ ] virtual/package-manager-2:0 [IP-] [ ] virtual/pager-0-r1:0 [IP-] [ ] virtual/service-manager-3:0 [IP-] [ ] virtual/ssh-0-r2:0 This is, I'd say, larger than what most distros with similar concepts would be doing, because most distros aren't source based, but it still lacks e.g. GTK. > emacs-23.x/emacs-23.1/src/emacs: error while loading shared libraries: libgpm.so.1: cannot open shared object file: No such file or directory > > Same here: GPM is a system-level feature. Sure, and someone removed it. GPM, when installed, still provides libgpm.so.1. I have libgpm.so.1, because the sysadmin of my system didn't remove it. You can tell your package manager to keep packages you need directly installed by marking them as needed. Using apt, this is done via 'apt install' or 'apt-mark manual'. Maybe there's some more admin-friendly way; I do not know. On Gentoo, you can create "sets", which are basically lists of packages given a name. For instance, I build Rockbox by hand outside of the package manager, so I have: ~$ cat /etc/portage/sets/rockbox dev-libs/crypto++ ... ... and I did 'emerge -n @rockbox' once. Now, packages listed in that file won't get removed. I have a similar file for Emacs packages: $ cat /etc/portage/sets/arsenmacs # Emacs packages I'm using. -*- conf-space -*- app-editors/emacs app-emacs/a68-mode ... ... so that I can sync them across machines. >> This is only avoided if C was also marked as wanted (or "manually" >> installed, or added to @world, ... depending on package manager). > > I don't know enough about this stuff, but if you are saying that the > sysadmin should have been more vigilant and should have paid attention > to such packages, then I submit that the defaults of the system > upgrade procedure are sub-optimal: the default should be to keep all > the installed optional features, not to remove them. That's the default on many distros, including the Debian-family one Fencepost appears to be running based on what I can glean in this thread. 'apt upgrade' does not also automatically run 'apt autoremove'. Most admins, however, instinctively do. Including me. > The only exception to this rule is when a feature is incompatible with > the new OS version (which is almost certainly not the case here: > libpng is alive and kicking on latest GNU/Linux, as are GTK/X11 and > GPM). I'm not sure what "GTK/X11" means. libgtk-x11-2.0.so is GTK2, compiled to use X11. So, that's GTK2. I presume you're referring to that. GTK2 appears to still be in the Trisquel repositories, so it certainly could be installed again. >> Incidentally, I went to compile Emacs 27.2 on modern glibc and found >> that there was, in fact, a real breakage: SIGSTKSZ on GNU/Linux is not a >> constant expression anymore (seemingly because some CPUs have started >> requiring varying sizes of stacks to save register pages), if >> _DYNAMIC_STACK_SIZE_SOURCE, which is enabled with _GNU_SOURCE. > > That's an example of a change in the environment which breaks > compilation of old sources. Yes, that's what I said. >> This happened in glibc 2.34; quoting NEWS: >> >> > * When _DYNAMIC_STACK_SIZE_SOURCE or _GNU_SOURCE are defined, >> > PTHREAD_STACK_MIN is no longer constant and is redefined to >> > sysconf(_SC_THREAD_STACK_MIN). This supports dynamic sized register >> > sets for modern architectural features like Arm SVE. >> > >> > * Add _SC_MINSIGSTKSZ and _SC_SIGSTKSZ. When _DYNAMIC_STACK_SIZE_SOURCE >> > or _GNU_SOURCE are defined, MINSIGSTKSZ and SIGSTKSZ are no longer >> > constant on Linux. MINSIGSTKSZ is redefined to sysconf(_SC_MINSIGSTKSZ) >> > and SIGSTKSZ is redefined to sysconf (_SC_SIGSTKSZ). This supports >> > dynamic sized register sets for modern architectural features like >> > Arm SVE. >> >> The workaround in Emacs was added in >> f97e07ea807cc6d38774a3888a15091b20645ac6. >> >> Though, this wouldn't have broken an already-compiled Emacs. > > Which is why I always keep binaries of old versions around. But, as > the examples above show, that is not always a solution, at least on > GNU/Linux with the current system upgrade practices. You could write a script that collects all system dependencies of a program and add them somewhere in the RUNPATH of the program. I know that Qt provides such a tool for Windows, but I am not sure whether it does so for ELF-based systems (where such a tool generally isn't used). >> >> If I removed libraries that my copy of Emacs 32 was linked against, it'd >> >> also "break" in the same manner, even though the Emacs 32 I have >> >> installed was built ~18 hours ago. >> > >> > Please drop the sarcasm. This is a real problem, not a joke. >> >> There was no sarcasm there. >> >> That was a direct and apt analogy that explains that the specific error >> here has nothing to do with the age of the code, or indeed any factor >> related to the code itself. > > Then it was a case of "reductio ad absurdum", also not useful. No, it wasn't, nothing was reduced out through analogy. The difference between the case I presented and the one you presented is a variable that is clearly unrelated to the problem at hand: the age of the program. The reason I found it important to show that this variable is not relevant is because it was specifically assumed that the age of the program was relevant in an earlier email. Incidentally, there really was a break in glibc 2.34, which was released in the interim, but it was not the break you reported. To conclude this section, about the removed libraries, no GNU (or otherwise) maintainer who lacks access to Fencepost can help prevent errors like the ones you've run into above. >> >> For instance, the example Eli gave, of programs "breaking" because >> >> GCC versions up to 14 failed to properly diagnose invalid C99, the >> >> correct interpretation is that the programs were only "working" >> >> (in air-quotes, because they cannot possibly be considered >> >> working, the same way as someone falling off a cliff is not truly >> >> flying) because GCC in particular did not enforce language rules. >> > >> > K&R syntax does not mean a program using it is broken, no. >> >> Not necessarily, no. A C99+ program using K&R-exclusive syntax is, >> however. > > There's no such thing as a "C99+ program", not when we are talking > about a long-living program originally written long ago. Instead, it > is the decision of the program maintainers to make it fully or > partially compatible with some C standard, which usually requires a > lot of work. Of course there is. Any program that is compiled by a C99 compiler needs to be a C99 program necessarily. Doesn't matter whether the first character written in the source code was written in 2026 or 1986. Indeed, K&R C Emacs is not broken if compiled by a K&R compiler, which can (or, at least, could; I do not know how good the emulation is now, 14 years on) be GCC. But it can't be GCC operating in C99 mode. > Emacs was using K&R for many years, and wasn't "broken" in any sense > of that word. Then, Emacs would be the first program I've ever seen that wasn't broken in some regard ;-) Most programs, indeed including most or all programs I ever wrote, are broken in some way that subtly manifests later. The point of stuff like static typing and compiler diagnostics is turning subtle future bugs into loud and immediate errors. This is strictly a beneficial thing to do, as I'll go over below. >> Which is precisely what I said: "GCC [...] failed to properly diagnose >> invalid C99". > > This makes no sense when we are talking about existing code. If it > doesn't adhere to C99, then it is NOT "a C99 program"; if a compiler > decides arbitrarily to treat is as such, the build will probably > break. Sure, that's why the -std=... flag exists. This is why I qualified with "if Emacs versions up to 2012 were telling the compiler that they were C99 programs". At a glance, ISTM that Emacs 24.1 indeed was using C99 syntax, and passing the flag, whereas Emacs 23.1 was doing neither, which means that, in this respect, it is OK. > IOW, it is the decision of the maintainer when and whether to need to > to diagnose invalid C99. The compiler has no say. Agreed. That's why -std=... exists. >> > The context here is the ability (or the lack thereof) to build a >> > program using old enough source code. >> >> That ability was never removed, as you know. > > Not removed yet. But, having read the relevant discussions, I won't > be surprised if it will become an error (thus the build will be > broken), and if the option to make it compile without warnings will be > removed at some point. And even if an option exists to treat these > diagnostics as warnings, seeing a deluge of warnings during a build is > not for the faint at heart, and having to dig for an option which > allows the build to complete, let alone shuts up the warnings, is also > not a very user-friendly situation. I don't think this is a solvable problem. Old programs (even ones written with care for portability) tend to make a lot of invalid assumptions. They make these assumptions because nothing stops them. Portability is considered achieved when the program source works on many systems, as you know, but the fact of the matter is that this is not sufficient proof that the program is actually always correct. For instance, many programs assumed that they can read a float through an int*, and this may have worked on every compiler and computer in the world at some point, but it is simply not correct. It's also semantically nonsensical. Presumably, also, this means the program made (likely invalid) assumptions about the layout of floats. It also made an assumption about the sizes of ints and floats. Etc. Many programs assume that a read of size four is atomic, but there's also no reason to assume that. It may have even been true on every single system they tried. But it could very well turn out not to be true on some machine, or it could turn out that the compiler eliminates that write at some point (which it cannot do with an actual atomic write), because according to the abstract machine it was unnecessary. I've spent years hunting them down and fixing issues like these. Obviously, some of these cases are not easy to diagnose and fix. But the K&R syntax removed from C99 is trivial to fix, even more trivial to diagnose, and causes many insidious bugs, while also confusing new developers and users. These years of fixing are what shaped my position. Had compilers been strict from the get-go, many of the issues I ran into would be detected at time of writing, and thus, such code wouldn't have been written. I also have first-hand experience as an educator, and know that the lack of strictness in historic GCC versions was a large detriment to new users of the GNU system. Now, don't get me wrong, there's no such thing as a "strict" K&R compiler, as there is no specification to conform to, and because real-world implementations were largely divergent. But there's no reason why ANSI C and onwards ought to suffer the same fate. My position on K&R C in particular is a bit more refined, though: those who care about K&R C - which I can't count myself in, given that in many years of working on toolchains and distros I've come across nearly no programs that correctly use K&R C and that could not be trivially updated to C99 - should attempt to formalize what GCC, glibc, etc ought to be doing for it. -std=gnu89 goes some of the way there, but I'm sure it's not enough. To ensure it stays working, you'd need to provide testcases that cover whatever you've formally decided is right, and be around to handle when it breaks. Also formalize how to enable this compatibility mode. Then, users could simply export CC='gcc -std=knr' or somesuch (perhaps even -std=gnu89 if it was extended to do the right thing always). >> > We are proud in providing the source code of each of our programs, >> > indefinitely, and consider that part of the software freedom of our >> > users. >> >> This is a point of policy, and an admirable and laudable one, that I >> wholeheartedly agree with, but... >> >> > But in reality, try to compile an old enough source tree, and you get >> > gazillion warnings and error messages, and in some cases the problem >> > will fail to build without a lot of non-trivial tweaking (which >> > requires significant expertise). >> >> ... this is a technical point, where Hyrum's Law manifests. >> >> (to those who have not heard of Hyrum's Law, its statement, in brief, >> is: "for a system with enough users [for which GNU qualifies, easily], >> every observable behavior will be depended on by somebody") >> >> There is no system in the world that manages to solve this, except by >> "simply" shipping era-appropriate copies of dependencies. > > My point is that at least in some cases we decide "not to solve" this > too soon. We could do better. Having a program break 25 years after > it was built is much better than if it stops working after 5, I hope > you agree. Absolutely, some such cases happened; I listed one such case above. (not saying that the break was unjustified.. it was quite an uncomfortable case) glibc, binutils and gcc releases are tested by various distros rebuilding their software against them. I, personally, don't have access to some massive build lab, so my personal testing is limited to rebuilding some three thousand packages (roughly 1/6th of all Gentoo packages) when there's a new GCC or glibc, but I'm not the only person doing such testing. RH and SUSE, AFAIK, rebuild RHEL and SLES against newest GCC and glibc while they're in RC. I know other Gentoo developers do similar testing. >> The system vendor (be it Apple or Microsoft or Google or whoever) simply >> ships you a set of dependencies dated to, say, some year, so the >> developer ends up seeing breakages when they change which date they >> attach themselves to, because they're the ones acting as integrators for >> the vast majority of their dependencies, and their code, with the >> vendor-provided code. >> >> The users end up not seeing this at all because each program gets >> distributed with nearly all dependencies, with the ones distributed as >> part of the OS being installed multiple times for differences in version > > You are talking about programs that are part of the OS. By contrast, > I'm talking about programs that were built by the user -- those are > not upgraded when the system is, and one of the worst effects of a > system upgrade is to see programs which worked for you for years > suddenly stop working. No, I'm not. My paragraph was worded a bit poorly, let me restate what I stated above, and expand on it: >> The system vendor (be it Apple or Microsoft or Google or whoever) >> simply ships you, the developer, a set of dependencies dated to, say, >> some year, so you end up seeing breakages when you change which date >> the system-vendor-provided dependencies attach themselves to, because >> you, the developer, are the one acting as an integrator for the vast >> majority of the dependencies, and your own code, with the >> vendor-provided code. >> >> The users end up not seeing this at all because each program gets >> distributed with nearly all dependencies, with the ones distributed >> as part of the OS being installed multiple times. These system-vendor-provided dependencies are equivalent to the "core" GNU system: GCC runtime libraries, glibc, coreutils, GTK2/3/4 (at some point at least), etc. These are in that year-versioned bundle that I was referring to, that gets installed a few times on each users' system. The dependencies outside of these, however (say, libjpeg or tree-sitter), are integrated by the developer, and get shipped with the program. So, when any of these dependencies - whichever category they belong to - change, builds break *for the developer*. The user doesn't notice, because it was made the developers' problem. The user just gets a ton of binaries, with all the parts epoxied together. But the user in our case is given source-code, and the freedom and compulsion to vary dependencies. Exactly as the developer was in these alternative models. The user becomes the integrator. It is not possible to avoid breakages as a result. Great effort is already taken to avoid them, yet they still happen. >> (those who have used MS-w are aware of "VC++ Redistributable XYZW" - or >> whatever the name was - which they have to install on occasion for >> various XYZW). > > That's just a packaging issue: those redistributables should have been > bundled with the program that needs them, but could not be due to > copyright issues and such. The important part is that, once you do > have the redistributable installed, no system upgrade will remove it. I'm not sure whether a MS-w upgrade by a major version would remove them. But, even if not, they're the exception to the rule on that OS; most dependencies are shipped with most programs, thus they're mostly isolated from each-other. Which is its own mess, of course (tried using TeXLive and Inkscape together through svg.sty? what a mess..). The issue we're discussing is also a packaging issue, though; programs in the Linux and BSD and ... ecosystems generally don't get distributed in binary form with all of their dependencies built in, they get distributed in source form, without dependencies. Whereas programs in the ecosystems I refer to above are all distributed in binary form with nearly all of their dependencies bundled. The former means that the same sources are expected to work with a myriad of combinations of various dependency versions. Obviously, the developer testing them all is unfeasible. Especially as many of those combinations do not yet exist at time of writing. Thus, problems arise sometimes quite late. This is where compiler laxness comes into play. I'll return to this below. >> This is also why many cling to static linking. > > Static linking is a two-edged sword: it could be more robust in the > long run, but in the shorter run you lose the ability to easily update > a dependency library if and when its developers fix some grave bug in > it, without the need to rebuild your application. > > Most programs nowadays use dynamic linking, IME. There's other problems with static linking also, but, yes, most programs are dynamic linked nowadays. What I was saying is that there's a contingent of developers who cling to static linking as a solution for the problems you lie out in this thread. Which are real problems. But they aren't problems solvable at the source level, or even at the binary level. We still try to, though. The solutions in the ecosystems I referred to above are far closer to static linking (because you can't really independently update components as the user) than what we usually do in the Linux and BSD and ... ecosystems. You can't have your cake and eat it, too. You either allow varying dependencies and thus have breakages, or you don't, and everything works (you even get gratis bugs because you can't independently fix them). I think we've largely made the right choice. The free software world permits anyone to fix problems that arise as a result of Hyrum's Law, and we're able to integrate masses of code written by many thousands of people and work on them collaboratively. But, this does mean that the constraint of "unmodified program works indefinitely" is impossible to satisfy. >> > One example of this is compiling a program that used K&R syntax. >> > E.g., Emacs switched to C90-style function definitions only in version >> > 24.1, which was released in 2012. All the older versions used K&R >> > syntax; they are now "broken" by your definitions, and cannot be >> > easily compiled. >> >> Well, yes, if Emacs versions up to 2012 were telling the compiler that >> they were C99 programs, but were not valid C99, they were certainly >> broken, and only worked due to a defect in GCC. > > See above: that's not what happens. In reality, the build invokes the > compiler without specifying the dialect, so whatever is the default C > dialect is being used. So when the default changes to be > backward-incompatible, it's bound to break old programs. Indeed, the default dialect can change. This is why I find the autotools choice to only provide -std=... conditionally dubious. >> Indeed, GCC should've been diagnosing those constructs back in 2012. Or >> 2000. Then, this situation would not have happened. > > Emacs was written in 1986, as you know. So 2000 would still be too > late. Yes, but many other programs weren't. Many more were intended to be C99 programs but were broken because GCC was too lax in enforcing C99 rules. Many such programs were written in the 2010s. >> In name of backwards compatibility, we've made many more incorrect >> programs to be "compatible" with. > > You make it sound like a sin, but I happen to think it's a virtue. > Backward compatibility is an important aspect of being user friendly > in my book. [below] >> I've argued before, and stand by it now, that source-level backwards >> compatibility should not be the default for compiled languages. When a >> compiler is present, it should only be backwards-compatible if told to >> be explicitly. > > This makes recompiling old sources harder, so I think it's a mistake, > unless we don't care about these case. I'm sure many more hours have been spent tracking down stuff that could've been prevented by stronger diagnostics than have been spent trying to compile old code. I do not mean to imply that backwards compatibility is a "sin". But, backwards compatibility in this instance means relaxing compiler diagnostics, thus making the compiler less strict. This is universally a disservice to users. I've went over why earlier, but I can restate it in brief again: anything that can be caught early but isn't harms everyone, including program authors and users. There are two different classes of users of compilers: program authors and program users building the source form. The former is harmed, substantially, by such default laxness, because they're enabled to write programs that are slightly wrong. The latter receives some slight relief from default backwards compatibility. But, this is a Pyrrhic victory for the latter: as a result of default backwards compatibility, rather than fixing defects in an early versions of programs, those defects go unnoticed are kept around long enough to break in more insidious ways later, blowing up in the users' face. Indeed, the case I showed in my last email with 'reallocarray' was exactly such a case: the user of flex "benefited" from default backwards compatibility, only to get a program that was slightly broken under specific conditions. Luckily, in that case, the breakage manifested as an easy-to-find crash. In many cases, it will manifest as a rare and difficult to diagnose runtime bug. Meanwhile the developer of flex was left unaware of this breakage for a longer time. It was a disservice to both classes of users to postpone or entirely omit diagnostics on code that GCC knew was very likely to be wrong. The driver behind the GCC 14 change was not that anyone else decided to do it (though arguably Clang doing it acted as a trigger), it was that we've been fixing related bugs for many years in many programs, and that we've been teaching students that "this code is not correct but the compiler ignored it because old code exists, but you shouldn't ignore it" (to very little effect). >> That's, obviously, not to say that we should break things willy-nilly, >> but the removal of certain K&R syntax from C99 was a considered move >> done long ago. > > I always thought that in the GNU project we don't blindly follow The > Powers That Be out there when they decide to remove or EOL something. > Instead, we make our own decisions, based, in no small measure, the > benefits and disadvantages for our users. Note that GNU developers are very much "The Powers That Be". Indeed, our hackers staff language committees and such. (though I don't think that was the case in time for C99; at least I can't find a reason to believe it was in brief archival research) This also isn't blind, the C99 change was for the best. As I said, a number of subtle bugs manifested as a result of such code being accepted. This was known even at the time. -- Arsen Arsenović
signature.asc
(application/pgp-signature, 418 B)
-----BEGIN PGP SIGNATURE----- iQECBAEWCgCqFiEE/uKz0RP8AKMWLWBhUsKUMB6ixJMFAmp7YFkbFIAAAAAABAAO bWFudTIsMi41KzEuMTIsMiwyXxSAAAAAAC4AKGlzc3Vlci1mcHJAbm90YXRpb25z Lm9wZW5wZ3AuZmlmdGhob3JzZW1hbi5uZXRGRUUyQjNEMTEzRkMwMEEzMTYyRDYw NjE1MkMyOTQzMDFFQTJDNDkzEBxhcnNlbkBhYXJzZW4ubWUACgkQUsKUMB6ixJO2 wQD/YTd7f2Gy/fNy2pu8qMFo9bEEhVBoLXSlddd6F0LD7MYA/24O0ynRAVj7nyTI AL/FsLM/wkTghUN8lWbatLx8THgD =eWWn -----END PGP SIGNATURE-----