- new
- past
- show
- ask
- show
- jobs
- submit
The article highlights a typical piece:
#if !(defined __GNUC__ || defined __clang__ || defined __TINYC__)
# define __attribute__(xyz) /* Ignore */
#endif
There is no reason that !defined check to not include a check for __attribute__ already being defined (a custom compiler author could then force an define for __attribute__ that translates to an internal __mycompiler__attribute__ replacement by default).But outside of that, just trying to compile on FreeBSD you often run into systemd dependencies or other non-posix behaviors (Not to mention on Windows but I'm not here to bring on flamewars so I'll leave that part).
Windows users singling out Linux users for not catering to their platform. How the times change...
> you often run into systemd dependencies or other non-posix behaviors
Not a problem. POSIX is irrelevant, systemd is great and we should all be using Linux to its fullest extent. Linux has great features and there is absolutely no reason not to use them all. Nobody complains about the fact BSDs have cool things like kqueue and unveil.
This goes back to the days I was browsing freshmeat and saw some interesting command line tool or otherwise non-UI tool from some hopeful developer for something useful. Node had significant traction but didn't really blow up until it became really cross-platform.
And perhaps is less of an issue these days since so many people use Mac's as their primary, so less Linux-isms survive once in context with osX.
> Not a problem. POSIX is irrelevant, systemd is great and we should all be using Linux to its fullest extent. Linux has great features and there is absolutely no reason not to use them all. Nobody complains about the fact BSDs have cool things like kqueue and unveil.
From following it over the year it was not entirely welcomed even in the linux community (and some of the security issues made one shudder). Mostly it's the monolithic nature that's makes it a questionable, is it Gnu/Linux these days or Systemd/Linux ?
kqueue is just an api, just like epoll, io_uring or even iocp on windows. And yes, it's a special case for high-perf servers where posix becomes less relevant (and while I can appreciate some lower-perf fallback to be able to develop/port to another platform like a console I do see that some programs are inherently platform bound).
I think one thing lost in my original comment was that I was often encountering things like this with "simple" CLI tools or lower level format libraries, and honestly projects like that also had a tendency to break over time without updates as they often relied on specific versions of libraries the maintainers had installed via Linux package managers, in the same fashion as npm has caused churn in the JS community. (npm at least has version pinning so old cli tools can often be run as long as node hasn't deprecated api's).
Yeah, and then we get "osX-isms" instead. Before node, there was rubygems which contained lots of macOS specific software.
Nothing particularly wrong with that. People should use their preferred platforms to the fullest. Why make it a point to single us out for "linux-isms" though? Makes absolutely no sense. BSD-isms, Win32-isms, macOS-isms are just as abundant.
> From following it over the year it was not entirely welcomed even in the linux community (and some of the security issues made one shudder).
It's definitely welcomed now. There's plenty of legitimate criticism against systemd but lack of standards compliance, incompatibility with other platforms or lack of devotion to some nebulous "unix way" religion aren't among them. The whole point of systemd is to use Linux kernel features like cgroups to the fullest extent, and it does so to great effect.
> Mostly it's the monolithic nature that's makes it a questionable, is it Gnu/Linux these days or Systemd/Linux ?
It's just "Linux".
GNU is not in any way special either. GNU, systemd, they're all just random user space stuff you can put on top of Linux. You can boot Linux directly into your software if you'd like.
It's strictly less monolithic than BSDs which ship a kernel and a whole bunch of system components and user space libraries you can never ever bypass because they explicitly don't guarantee ABI stability like Linux does. To say nothing of macOS which becomes more of a walled garden every day that passes.
In my experience this was a problem over 25 years ago when I developed for Solaris and other non-Linux operating systems.
So I suppose it does have a marketing benefit in that I now use Linux.
Surprised about FreeBSD. My experience is that porting Linux software is usually pretty easy as long as it's not using some Linux-only feature (io_uring for instance).
I'm not sure why you're surprised, the parent of you comment clearly stated
"on FreeBSD you often run into systemd dependencies or other non-posix behaviors"
which means, software written for Linux often uses "Linux-only features" such as systemd and other non-posix dependencies that are foreign to the BSDs and traditional UNIX. Thus, it shouldn't be surprising that Linux software is hard to port to the BSDs.
Linux used to be a pretty good UNIX, I'm not sure what it is now.
And BSDs are just as happy to accumulate nifty features like kqueue, unveil and whatever else it is that they have. These features are all just as foreign to Linux as io_uring is to them, and just as non-POSIX compliant.
Yet somehow I just don't see people complaining about them endlessly the way people complain about "linux-isms". When I see such features I am very impressed because I think they're amazing innovations, and my only reaction is to wonder when Linux will gain the same features so it can be just as great as they are.
Linux has become Linux, it's own thing that as often as not says "yeah, that old Unix stuff is fine for you boomers and other fossils...we're going to be over here doing our own thing". Which is probably fine, I guess, because all the old Unix versions did the same thing to some extent and the computing world had changed over a dozen times since Unix showed up. Unless you were on one of the minimally massaged System V reference ports, going from one vendor to another was anything between "lots of annoying differences that make life less fun than it could be" to "WTF said this was Unix and why did you make me touch it?". Ultrix, SCO and UTek (among many others) weren't awful. Solaris and HP/UX had some vendor-only things that were hard to replicate. AIX made you question your life choices, especially if you wandered off into one of the mainframe versions; you had clearly angered the gods.
There used to be Windows, Unix, and everything else. Now there's Windows, Linux, and everything else, with Unix (BSD mostly) being part of everything else. Times change, shit happens, and there's only so much that impotently shaking your fist at the unjust universe will fix.
https://learn.microsoft.com/en-us/cpp/build/reference/zc-pre...
I don't expect anyone writing GUI tools or more high-perf servers to spend their time porting to other platforms (trying to compile GTK on Windows wasn't for the faint of heart).
“All the world's a VAX”
https://groups.google.com/g/comp.lang.c/c/CYgWkWdWCcQ/m/thMt...
#pragma immutable_macro __attribute__
After this pragma, any attempt to #define/#undef the macro "__attribute__" will be silently ignored. This lets us (or our customers) bypass such stupidity in library headers. It's also often useful to replace broken macros with working versions.2: You could easily compile Samba yourself for FreeBSD in the past, last time I tried a new version it broke in what I remember being due to linux-isms (yes there is ports, but being reliant on older versions if ports maintainers can't keep up isn't a good thing).
3: The only "fairly basic" stuff that's hugely different is mostly the absence/reliance on shell-scripts (when building), but that has little to do with the actual code function (Personally I often used Node scripts in those scenarios, Python scripts would probably be an improvement since there's no reason it couldn't be everywhere).
I used to use Tremor to decode Ogg audio (no UI needs, just binary data in, arrays of primitive values in audio buffers out), early versions were easy to compile under Windows but building later versions were buried in shell scripts generating headers,etc for no real good reason (maybe to help port when working on a Linux workstation to other embedded devices but made the code less easily compilable by default), the core functionality only really needed a C compiler as early versions showed.
I can agree that something with advanced UI's like Blender (that relies on GL/3d rendering for UI) might not be easily portable, but when algortihm libraries often requires heavy reworking it's not a good thing (Here I think Github has helped since people has had an easier time to contribute, it's a sad thing that people are moving away due to the AI-crap).
In the end, it's not about _actual_ differences but more of a superiority complex of Linux users that is the main roadblock.
How many times have we been told that we're entitled freeloaders for expecting Linux compatibility work from others? Insulted by people who use dominant platforms that get all the commercial support while we get literally nothing? Reduced to reverse engineering stuff with no documentation and zero help?
Pretty wild to watch this unfold. Now that Linux is finally coming out ahead, as it should, because people are finally writing software for it... Suddenly we're the bullies.
I worked in gamedev, consoles, etc. Linux support was often discussed but the whole mess of different libraries on various distros vs static library linkage legality, evolving audio api's,etc was real blockers (Valve just defaulting on Wine and Win32 binaries for steamdecks could be discussed at length).
Honestly, could even be posited that the rise of the Web as a delivery platform, Java and Node,etc is in large part DUE to the fragmented story of much of C/C++ code platform-tiedness, Linux just happened to move ahead due to it's momentum as the "free" option (quotation marks due to Android).
You have the source code and it's literally free software. What else do you need?
It's honestly pretty incredible to hear complaints like "it didn't compile on my preferred platform unchanged".
> the whole mess of different libraries on various distros
All the various Berkeley Software Distributions out there don't have different systems and libraries of their own?
This is a user space problem anyway. Linux kernel is actually better here. Linux actually lets you bypass system libraries and talk to the kernel directly. You can write Linux applications in freestanding C and they will work. BSDs will eventually break ABI and your program if you do that.
> static library linkage legality
Nothing illegal about it. Just gotta follow the terms of the GPL. Whether you're willing to do it is a completely separate matter.
> Valve just defaulting on Wine and Win32 binaries for steamdecks could be discussed at length
Don't think there's any discussion to be had here. It's just the pragmatic choice that buys us access to vast amounts of existing software that will never be ported. Linux kernel is even gaining NT functionality now just to support this. Nothing wrong with it.
You can totally get Linux versions of games in the Steam Deck, it's just that they're often second class ports, outdated and generally forgotten by all including the developers. There is no reason whatsoever to sit around waiting for things that will never come.
Where have you been for the last quarter century?
In the late 90s-early 00s we had SystemV, Linux, BSD, macOS and the market begged for standards like POSIX and to an extent CDE and many other proposed ones. As the largest player, Linux always had an attitude.
Now, after winning the Server, embracing, extending and extinguishing the Workstation/Desktop(WSL, Valve), and with a foothold in mobile(Android) Linux is the de-facto standard.
The BSDs have declared POSIX dead and gone their own way while supporting Linux(SystemD, Wayland) APIs even if they are more half-baked than POSIX in order to benefit from what is now virtually a Linux ecosystem.
I don't like this any more than you but it is what it is.
Then there's portability between compilers, which, as the article notes, glibc is also completely hostile to (except for anointed compilers) for no good reason whatsoever.
This is neither true nor claimed by the article.
It doesn't work. For no good reason. Because there are a few anointed compilers.
That it wasn't on purpose doesn't make it not hostile.
Which is at least better than with MSVC, where they did everything differently, and only half of it.
That said - I think a rule-of-thumb one can follow is that any inclusion of a file with a directory prefix, especially `<sys/whatever>`, needs a guarantee-of-availability in your build configuration phase, e.g. CMake `find_package()`, or or at least `check_include_file()` and such. That way, you might be more likely to fail to build, but at least you'll be telling the user "I expect these things to be present".
I don't like systemd but it is a lesser evil.
Meanwhile people still have issues on turning off their machines.
There are quite a few init systems: The venerable sysvinit, runit, s6, openrc and others. You don't like upstart? Ok, choose another one, there are many. Here is a comparison table by the Gentoo folks:
https://wiki.gentoo.org/wiki/Comparison_of_init_systems
As for the claim of "almost all sysvinit scripts contained several bugs" - that's both hyperbole and false. Plus, you seem to be implying that systemd has not been troubled by bugs, which of course it has (and that does not disqualify it; the fundamental design and organizational nature as a project are the disqualifiers).
One bright spot is systemd-networkd allows one to change quite a few things about interfaces in the way server automation platforms expect to work without doing a network restart. The workaround otherwise on, say, CentOS was always to write the new config file used by future restarts, also run CLI commands to update things in memory, and be sure to tell the service not to trigger a restart on the config file(s) changing. Otherwise if you’re doing something like streaming UDP video your own automation can become a reliability issue.
Systemd bothers people because it's not "the Unix way". In other words, it's not some painful lowest common denominator POSIX nonsense. That's a feature, not a bug. POSIX is garbage and restricting oneself to it is pure masochism.
Every unixlike deviates from POSIX and for good reason. That includes the BSDs, but somehow I don't see people complaining endlessly about all the nifty exclusive features they keep accumulating for themselves. Why is it that only Linux gets singled out?
Wait.
The point was that using systemd is somehow "mandated". It's not, people chose systemd because it's actually better and made life easier compared to some POSIX nonsense.
The point was that this non-existent "mandate" caused a "bifurcation" from "standards-based" software to Linux-specific. If anything is being "mandated" here, it's the POSIX compliance. Nobody is obligated to follow this like it's some sort of religion. The standard is garbage and should be forgotten.
The point was that systemd was "the bane" of FLOSS. Systemd is itself FLOSS, it's literally GPL'd. And pretty good FLOSS at that. It's just not "standards compliant" which makes it heretical or something. Total nonsense.
There are no "strawmen" here. Just downvote silently if you disagree and don't want to argue.
If you're using RedHat or Debian and most of their derivative distributions, it is.
> people chose systemd because it's actually better
No, they did not. Most people did not choose systemd, their Linux distributions did.
RedHat chose their own system for their own distributions; on Debian, a controvertial process foisted it onto the distribution using gaslit rhetoric; and I don't know much about the process elswehre.
> The point was
That was not the point.
> It's just not "standards compliant"
This is the straw man you've created. Neither my post nor most critique of systemd regards "standards compliance".
Use a better distribution.
Arch Linux has entire wiki pages dedicated to alternative init systems. Anyone can download, install and use OpenRC or whatever they want if they really care enough. People actually took the time to document the process.
Linux is whatever you make of it. There is nothing stopping you from installing whatever you want. I could write an init today and start using it immediately. I don't need anybody's permission to do it.
> Most people did not choose systemd, their Linux distributions did.
By "people" I meant the people who make and maintain the distributions. They're the ones who actually choose what to ship in their projects. Users either accept it, look elsewhere or take on the maintenance burden unto themselves.
No doubt they chose systemd because it made their lives monumentally easier. Maintaining my own computer with systemd is pretty much painless. I don't even remember what it was like before.
> Neither my post nor most critique of systemd regards "standards compliance".
> we've started to see this sort of bifrucation of a lot more FOSS away from being standard-based and multi-platform to being Linux-specific.
No idea what "standard" you're referring to if not POSIX.
[2] https://github.com/fuhsnn/slimcc/blob/main/slimcc_headers/pl...
Some more fun stories:
- Game projects default to using SIMD so for example SDL and STB you always need to pass -DSDL_DISABLE_IMMINTRIN_H and -DSTB_NO_SIMD
- math.h's NAN usually fall back to (0.0f / 0.0f), which will print "-nan" with printf, some projects test suite fail because of it (they expected "nan").
- NetBSD's sys/cdefs.h straight up #error's if you don't pretend to be GCC or PCC.
- Some projects can't compile without __attribute__((always_inline)) because they use it on non-static functions.
- Many projects probe -fvisibility in the build system and pass -fvisibility=hidden to compile, but in the headers they gate __attribute__((visibility(default))) behind __GNUC__ checks, so you'll get missing symbols.
- Some projects use if(0) { undefined_function() } to fake static_assert(), there is even a bug report from QEMU to Clang because it failed to optimize in -O0 a certain `if` written this way.
- Even if you define __STDC_NO_VLA__, projects might fall back to alloca() code path that's untested and broken (python and jemalloc both had this problem, already reported)
- Valkey has broken __builtin_ctzll fallback nobody noticed (reported).
- Zig's C bootstrap path expects the compiler to have GCC/Clang-tier optimization and stack overflows if you don't (reported).
- I contributed stdatomic.h code path for Ruby just to compile it with slimcc, pretty sure it's still the only user of the code path.
- I implemented __has_extension in the hope that projects can use it to query gnu_asm; but SQLite broke because they use __has_extension(c_atomic) to query GNU atomics builtin, but c_atomic actually is meant for C11 _Atomic (IMO they should use __has_builtin)
But I think the power dynamics is crucial. In the Lisp ecosystem the users have great power, (and there are dozens of implementations,) so it's not like one or two implementation decides what everyone is gonna use and everyone just lives with it.
+ #if !(defined __GLIBC_COMPILER_SUPPORTS_ATTRIBUTES__)
- #if !(defined __GNUC__ || defined __clang__ || defined __TINYC__)
# define __attribute__(xyz) /* Ignore */
#endif
(or probably a more fine grained for each attribute they try to use)Considering such checks are fairly conventional in downstream C++ libraries based on compilers (for example checking OS platform or compiler, e.g. [Boost.Config](https://www.boost.org/doc/libs/latest/libs/config/). Modern C++ even went ahead and standardized this somewhat https://en.cppreference.com/cpp/utility/feature_test )
It's probably just natural for software developers (myself included), whenever only FooZoid v5 supports frobnicate(), say "#ifdef FOOZOID_V5" and go back to your business, rather than introducing "FROBNICATE_SUPPORTED".
Also, when you try to ask for a feature flag in the code review, people will throw YAGNI at you, and they might be not wrong, at least for the first few years. After that, it's a costly refactor.
One step of the 2024 supply-chain attack on xz utils was to disable a security feature by introducing a feature test with an intentional typo. Even knowing that this commit[0] contains an intentional typo, I had to re-read the diff a few times to actually find it.
[0] https://git.tukaani.org/?p=xz.git;a=commitdiff;h=a100f9111c8...
It's an interesting point though that the parts of a program that don't fail loudly are prone to having bugs go unnoticed.
Dealing with the preprocessor (essentially a different, crippled language) was too much headache at the start so I just used `cpp`, and at the end, I was just too lazy to implement it, so continued using `cpp`.
(BTW: Anyone else here ever used the Cosmic C Compiler for Motorola microcontrollers? Amongst other idiosyncrasies, it had only one datatype - `byte` - and I had to implement macros to do 16-bit arithmetic operations. That project was easily the worst development experience of my life.)
What I want to explore is cheap and fast optimizations, without SSA and data flow tracking. I have huge sources files compiled to 25MB .o files, which should need to be compiled in less than 5m. So far only tcc can do that. But I have now consteval and deadcode elimination for free. Which tcc cannot do.
Tell me about it. :-)
make FC=ifx check
On my Fortran projects, that will run the tests with Intel's Fortran compiler. The Makefile has logic to automatically change compiler flags as appropriate. I default to the GNU Fortran compiler, so `FC` isn't required.I have made a script to run through a series of compilers by alternating between `make check` and `make clean`.
I have separate Makefiles for GNU Make and NMAKE/jom. My Fortran code works fine on various Linux distributions and Windows, though I'll add that achieving that is probably easier with Fortran than C. I've also tried a BSD Make that worked (on Ubuntu at least). My Makefiles are pretty close to the intersection of POSIX and NMAKE, so the main differences between the different Make versions are the conditional statements needed to handle the different compiler flags and the include statements (as I put the compiler flags in separate files).
In practice, the compiler is an often an omitted dependency of any c code.
Is this because Apple at some point stopped updating GCC because of the GPL license change? I think GCC 4.2.x was the last GCC licensed under GPLv2. Could be for compatibility reasons for Mac software.
I've written quite a bit of C code and do not know that to be a rarity. Especially when it comes to libraries rather than applications, and FOSS as opposed to proprietary code.
> Most real world C code out there relies on non-standard behaviors and language extensions to varying extents
Maybe it depends on which domain you're working in. At companies whose target platform is not a PC, relying on idiosycratic behavior, or extensions, is difficult: The compiler for the target device may simply not support the bells and whistles of GCC or whatever, so you stick to C99, (or even C89, ugh) to be on the safe side. And even then there will be things which are standard, but... well, I would be wary of relying on them being supported robustly enough, e.g. variable-length arrays.
And of course, once your code does not target just one single machine then you're forced to have to worry about portability and standard compliance etc.
Well linux exclusively usages gcc to compile.
Clang happens to implement gnu11, I think it's the only non-GCC compiler to do so.
For a long time only Android Linux kernel downstream supported it.
We need more betterC compilers, we have one (five if you count C3, ZenC, SafeC and Zig but they are not betterC)
And we need more assemblers.
https://github.com/dlang/dmd/blob/master/druntime/src/import...
https://github.com/dlang/dmd/blob/master/druntime/src/__impo...