-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Drop C89 support? #6691
Comments
One of the things I want to be aware of is the impact of code changes in SDL 3 affecting merges between SDL 2 and SDL 3. We're going to be supporting both and fixes in one are likely to be wanted in the other, so I want to be careful that we're not making that harder by lots of sweeping code changes. |
What shall we really gain from all this? Namely:
Our types are already
And change size of SDL_bool from 4 (
I'd say blah, but suggest that you keep out of public headers: you |
Hello, Speaking of the N-Gage: A parting with C89 would also be the end of the Nokia N-Gage port. The Symbian S60v1 SDK neither provides An update to a more modern compiler would be a possibility, but it would also be anything but trivial. Support for ARM PE executables has been dropped after GCC version 4.6.4 in 2013. However, support was deactivated much earlier by default. But out of sincere interest: what would be the notable benefits of parting with C89? My two cents. |
Technically, SDL already depends on Personally, I think the best approach might be to move the replacements into (Also, it would be really nice if SDL had |
Fwiw, I had this listed on the old trello wishlist where I was making notes, but in recent years I'm wondering how much this would help optimization vs cause really hard to debug problems. |
So when I spoke to Sam about this earlier today, I thought we were talking about dumping all the configure details and moving to stdint.h to give us access to reliable types that we can use for setting up our own. So our headers end up looking like: #include <stdint.h>
typedef uint32_t Uint32;
// etc (and maybe we end up with an But if we're talking about moving the whole codebase to stdint types...that's a hard no from me. On a basic level: literally nothing will ever merge cleanly back into SDL2 if we make a change like that. But also I personally love using |
With that out of the way: there are three things I really want in C99 and miss like a lost tooth every time I write SDL code:
The cons are:
Also note that I think it's reasonable to keep the public headers as C89 in any case, so people can use whatever compiler they want for their own project and still link against SDL. |
In the FNA community we have something called "VS2010 C", which is basically C90 with stdint. We target this because A: XNA stopped with VS2010 so we just happen to support that exact version, and B: It gives all the obvious features like stdint and flexible comments that the non-MS compilers have supported forever, while also adhering to a lot of the requirements that genuinely old compilers would care about (like variable declarations). It's a very weird and obscure standard to target, but I don't think FAudio or FNA3D have ever gotten bugs from any platform regarding our C standard minimum so it seems to act as a nice compromise between "compatible" and "modern" C. |
I think one needs to be a bit careful when using these. Not only do they differ between different platform, they are not necessarily faster than the fixed-sized equivalents. For example, on 64-bit Linux int_fast16_t and int_fast32_t are 64 bits. I don't know in what situation it's actually faster to use 64-bit integers instead of 16-bit or 32-bit on x86_64, perhaps with some hardware or under certain circumstances? But it certainly wastes memory, which could lead to more cache misses, especially if you store a lot of them in some data structure. One place where I've seen it resulting in poorer performance is in the C++ standard library. The standard random number generators that were introduced in C++11 are defined in terms of these "fast" integer types. This is especially bad with the 32-bit Mersenne Twister (mt19937) which uses uint_fast32_t. On 64-bit Linux this leads to it using twice as much memory than necessary (5 KB instead of 2.5 KB) and it also runs slower according to my own tests. |
While I'd definitely prefer a switch over to the stdint types (that's where my muscle memory lives these days), I do see the point. (And while we could do some slow transition, where we make the public API use stdint types, but keep using the SDL ones under the hood until SDL2 isn't seeing updates anymore, that's ugly in its own ways. IMHO, it's the API's types that are more important — both because we can't break them, and because that's where a difference from "what everyone else is doing" hurts most, with things like bindings generators.) One thing that's probably worth doing, and explicitly stating (since I think it's already the case), is guaranteeing that — where there is an equivalent stdint type — the SDL definition will be identical, so they can be used interchangably. This is something which hit the Linux kernel's similar definitions, where there were concerns that things like alignment wouldn't match.
Those are also the biggest wins in my book. I could add to them:
Most of those are supported even by older compilers because C++ has them: if you drop designated initializers and So +1 for "MSVC 2010 C" as a compromise. And relatedly, curl just decided not to move from C89 → C99.
(I may have hacked together an stdbool.h for Borland C++ 3 yesterday for another project… Of course, even C89 doesn't help you with segmented memory models or tiny variable name length limits. :-P) |
I think the intention is you'd be using these in local variables as for-loop counters, not in arrays and structs, but that even the standard C++ library implementations didn't understand this demonstrates it was an idea destined to backfire. |
I think after discussion, we don't plan to move to stdint/stdbool as the datatypes we use in code. This allows us to more cleanly merge changes between SDL2 and SDL3, and makes it possible to support older compilers. Our types will be compatible with those though, so users of the API have the flexibility to use whichever types are most comfortable. |
Just a quick question about the integer types: in some places there are still uses of Might as well also throw in this question while I am at it: I doubt it, but has there been any thoughts of a |
I think the intent is to match the underlying APIs. If you have a list of functions you're curious about, let us know and we can review them. I don't see a specific reason why SDL_Vulkan_GetInstanceExtensions() would use an unsigned vs a sized type. Feel free to enter an issue and we'll look at it for 3.2.0.
A |
@mupfdev, does the N-Gage SDK support |
I'm strongly in favor of moving up to at least C99 for SDL3. Intermingled declarations alone is worth it, plus one-line comments, designated initializers, compound literals, better (variadic) macro support, even C11/C17 gets _Static_assert, type alignment specifiers, and _Generic, which I think are nice to have, but probably wouldn't have a major impact on the project day to day, like intermingled decls and simple comments. (I'm excited for C23. Already enjoying |
I'll add to this that there's inconsistencies between standard library implementations (and compiler freestanding headers). As you note, Glibc uses wordsize for 16 and 32 bit fast integer types, but musl uses 32-bit for both, newlib tries making them int/unsigned int if they fit and [u]int_least[N]_t otherwise, bionic and uClibc match Glibc, etc. |
The SDK currently uses an old version of GCC, I have tried to compile this version before, but failed. |
@mupfdev GCC 3.0 is apparently the earliest version that supports declaring variables in the middle of a block, so it might just be a small step up: https://gcc.gnu.org/c99status.html |
Another possibility is to use a common subset of C99 and C++98, so that older compilers could still use features like |
I agree with @mupfdev , although for different reasons, because I don't write for the ngage. I consider C89 support a very good value, because I'm the kind of dude that writes code thinking that it will last decades not only frontwards but also backwards. Personally, I have used some C99 and C11 stuff in the past, but, today I find myself preferring to stick to C89. And yes, I don't write single line comments either... I consider it like a way of saying "I won't write C++ never again in my life" 🤣 |
I'm running into this upgrading hidapi to the latest version. Let's update to @ccawley2011, @flibitijibibo, @madebr, how do we enable that in CMake? |
|
Speaking about c90, I will enable strict c90 on the tests. |
I have the declaration after statement block removed in a pending PR: |
I am resisting the urge to go through every file and move all the variables around, because it'll make merging back into SDL2 hard...but I'm absolutely going to start (over)using this in new code. So if you're not absolutely sure, say so now! (it's okay to say this restriction is lifted only for hidapi, because it presumably isn't going to support the platforms that would have an ancient C compiler anyhow and we can just exclude hidapi completely for those targets. But if we're doing this in SDL itself, I'm 100% using these features like crazy.) |
Okay, I guess it's settled then. No Symbian support in SDL3. 😔 But if it helps the majority, then I don't want to stand in the way of that. |
Line comments are not a problem, provided they aren't used in public headers. |
Where can I download a symbian toolchain (docker), Perhaps there are ways to work around. |
The compiler is downloaded by the toolchain via CMake: https://github.com/ngagesdk/ngage-toolchain The Symbian port is labeled "N-Gage", because it specifically targets Symbian S60v1. It's part of SDL2. This is how I update the precompiled version of SDL2 for the toolchain. Not elegant, but it works. Haven't had the time to implement it in the official https://github.com/ngagesdk/SDL
|
You mentioned that you could potentially upgrade the version of GCC in the SDK? Mixed declarations are supported in gcc 3.0 and onward, so anything newer than what you have should work. |
It's a bit annoying the ngage sdk downloaded by https://github.com/ngagesdk/ngage-toolchain only runs on Windows, and needs 32-bit cygwin, which is EOL. None of the mirrors provide a 32-bit cygwin1.dll. I found this (old) and this (recent) effort to get the toolchain building on modern systems. |
I merged my change, so let's call it. SDL 3.0 will use C89 with |
Can we please add some cmake magic to set C99 + extensions (e.g. |
Just in case anyone here is able to provide some help with C99 support for the N-Gage. Any help is highly appreciated: ngagesdk/ngage-toolchain#9 |
Hey, where did we end up with variable declarations in loops? Like, instead of this... int i;
for (i = 0; i < 10; i++) {} ...we do... for (int i = 0; i < 10; i++) {} ...was this considered safe? |
Yep, just not in any code that is backported to SDL2. |
What does @libsdl-org/a-team think about dropping C89 support?
Off the top of my head, we can drop Sint*/Uint* in favor of types in stdint.h, we can potentially drop SDL_bool in favor of stdbool.h, we can use // comments, etc.
I think all the compilers for platforms that we support have a C99 or newer mode available.
Thoughts?
The text was updated successfully, but these errors were encountered: