Thread: C11 / VS 2019
I propose that we raise the baseline C standard for PostgreSQL to C11 for PostgreSQL 19. This will allow us to make use of some new features, clear away a bunch of backward compatibility cruft, unify use of compiler-specific extensions, and narrow the range of compatibility concerns for some efforts like improved threads support. Most compilers other than older versions of MSVC (about which see below) have supported C11 for quite some time and most use it by default, so for most developers and packagers this wouldn't effectively change anything except removing some restrictions about what features they can use. (I mentioned some of this in my presentation at pgconf.dev; I will repeat the relevant points here. You can see my presentation at [0].) [0]: https://www.pgevents.ca/events/pgconfdev2025/schedule/session/271-what-is-new-in-c-and-posix/ Here are some of the features we could use. This is just for inspiration right now, these would all be separate proposals: - alignas specifier to allow specifying larger alignments more portably, e.g., for direct I/O - noreturn, already in use but would allow removing backwards-compatibility code - static assertions, we currently have 12(!) different implementations for this, could maybe cut down to 2 - allow typedef redefinitions, to untangle header files (see for example recent discussion [1]) - anonymous unions, mostly aesthetic - generic selection, for some more type safety in certain cases - threads library (needs separate consideration, see [2]) - atomic types, to maybe simplify some of our atomics support [1]: https://www.postgresql.org/message-id/f36c0a45-98cd-40b2-a7cc-f2bf02b12890@eisentraut.org [2]: https://www.postgresql.org/message-id/flat/CA%2BhUKGLtmexrpMtxBRLCVePqV_dtWG-ZsEbyPrYc%2BNBB2TkNsw%40mail.gmail.com (Note: While the term "threads" appears here, this is independent of any work on a multithreaded server. It probably wouldn't hurt, but it's not a hard prerequisite as far as I know.) The minimum required compiler versions for C11 support among the most common compilers are: - gcc 4.6/4.7/4.9 (depending on what feature) - clang 3.1/3.2/3.3 (depending on what feature) - Visual Studio (VS) 2019 (2022 for threads) I have also checked the following less common compilers: - Oracle Developer Studio 12.6, which is in the buildfarm, supports C11 ok (manually tested) - Intel ICC 17.0.0 is ok (not in the buildfarm, tested on godbolt) - AIX xlclang, which is currently not supported but might come back, also supports C11 I think this covers all relevant compilers. Visual Studio details: As shown above, C11 would require VS 2019. The current minimum version required by PostgreSQL 18 is VS 2015. Can we move forward from that? There isn't much data to extrapolate a VS version support policy from. When MSVC support was initially added in PG8.3, it required VS 2005, which was just the latest at the time. Then it was not changed for a long time, until PG12 required VS 2013, which was exactly for the C99 support. Then it was changed once more for PG16, requiring VS 2015; AFAICT, this was just to be able to clean away some conditional C code. I don't recall any complaints about any of that. Note that PG12/VS2013 corresponds arithmetically to PG18/VS2019, so making a move in PG19 would be less restrictive than that previous change. I'll also note that we haven't had any test coverage for anything older than VS 2019 for quite some time. I also remember commit f9f31aa91f8, where we discovered that the code didn't build with VS 2015 after one year, and that was two years ago, so it seems like there isn't too much interest in trailing edge VS versions in general. So I feel comfortable moving this forward. GCC details: The oldest gcc version that we currently need to support is gcc 4.8, which comes with RHEL 7. As alluded to above, some C11 features came later with gcc 4.9, specifically generic, threads, and atomics. I think it would still be useful to move forward without those features. Threads and atomics are out of scope anyway because they require VS >=2022, which I'm not prepared to require. And generic, well, we'll just have to do without that for the moment. We can of course have a separate discussion sometime about when to drop RHEL 7 support, but it doesn't have to be a prerequisite for this. (Both gcc pre-4.9 and MSVC pre-2019 do support thread-local storage, just not the C11 spelling, so this is at least on paper not a blocker for a multithreaded server.) Clang details: I don't think anyone cares about clang versions that old. There is a clang 4.0 in the build farm, but I don't think even that has any practical relevance. I would also set the minimum supported C++ version to C++11. This is the level required for, for example, static assertions (and also threads and atomic types), so it makes some sense to align this with the C side. Compilers tend to implement C++ features before C features, so this wouldn't set any additional requirements on compiler versions in practice. Summary: 1. require VS 2019 2. use C11 Thoughts?
03.06.2025 07:51, Michael Paquier wrote: > On Mon, Jun 02, 2025 at 08:52:00AM -0500, Nathan Bossart wrote: >> On Mon, Jun 02, 2025 at 05:44:12AM +0200, Peter Eisentraut wrote: >>> Summary: >>> 1. require VS 2019 >>> 2. use C11 >>> >>> Thoughts? >> >> +1 > > +1 to move on for both of these. I got convinced about the benefits > of C11 and the simplifications we could get from it in the Postgres > code base during your presentation at pgconf.dev. > > Dropping VS 2015 and going up to VS 2019 brings other benefits, > __VA_ARGS__ coming in mind. I am wondering what's the state of > locales, actually. We've had some pain with VS 2015 as we lacked > locale_name in _locale_t, for example. That may be worth a second > look to see if some simplifications can happen in this area. I don't > think so at quick glance through the VS docs, unfortunately, but I may > be wrong, of course.. Will it mean we can implement atomics in term of C11 atomics? Aside for VS 2019, which has no support for. (But VS 2022 already has.) So instead of numerous variants we could just differ VS2019 vs plain C11. -- regards Yura Sokolov aka funny-falcon
Yura Sokolov <y.sokolov@postgrespro.ru> writes: > Will it mean we can implement atomics in term of C11 atomics? Any such change would have to be supported by extensive performance testing to verify that there's not a regression on any supported platform. Yeah, it'd be cool if we could rip out a lot of that code, but we aren't going to just rip on faith. regards, tom lane
On 03.06.25 06:51, Michael Paquier wrote: > Dropping VS 2015 and going up to VS 2019 brings other benefits, > __VA_ARGS__ coming in mind. Yes, this was going to be my next step. As we're already talking about it, here is my proposed patch. For an explanation, the background is that MSVC has a "traditional" preprocessor and a new "conforming" one. The latter is available starting in VS 2019, but it's not the default. We have some code, especially around __VA_ARGS__ that specifically caters to this traditional preprocessor. Turning on C11 mode in MSVC (/std:c11) automatically turns on the conforming preprocessor, which would currently break compilation on MSVC because the code expects it to be in traditional mode. So my first patch is that we fix that bit and turn on just the conforming preprocessor (/Zc:preprocessor), without turning on C11 yet. That way, we get that part out of the way, and we update the documentation about requiring VS 2019. (And we'd flush out anyone who might still be running pre-VS-2019 build jobs somewhere.) Later, when we turn on C11, we can remove the explicit /Zc:preprocessor option again. (An alternative approach would be to turn on C11 and add another option to explicitly turn the traditional preprocessor back on, but that seems pointless, and the documentation also suggests that that combination is not well supported.) So the attached patch is my proposal to commit early in PG19.
Attachment
On 03.06.25 10:01, Yura Sokolov wrote: > Will it mean we can implement atomics in term of C11 atomics? > Aside for VS 2019, which has no support for. (But VS 2022 already has.) > So instead of numerous variants we could just differ VS2019 vs plain C11. I wrote: """ GCC details: The oldest gcc version that we currently need to support is gcc 4.8, which comes with RHEL 7. As alluded to above, some C11 features came later with gcc 4.9, specifically generic, threads, and atomics. I think it would still be useful to move forward without those features. """ So there is additional homework to do there.
On 04.06.25 08:15, Peter Eisentraut wrote: > On 03.06.25 06:51, Michael Paquier wrote: >> Dropping VS 2015 and going up to VS 2019 brings other benefits, >> __VA_ARGS__ coming in mind. > > Yes, this was going to be my next step. As we're already talking about > it, here is my proposed patch. > > For an explanation, the background is that MSVC has a "traditional" > preprocessor and a new "conforming" one. The latter is available > starting in VS 2019, but it's not the default. We have some code, > especially around __VA_ARGS__ that specifically caters to this > traditional preprocessor. > > Turning on C11 mode in MSVC (/std:c11) automatically turns on the > conforming preprocessor, which would currently break compilation on MSVC > because the code expects it to be in traditional mode. > > So my first patch is that we fix that bit and turn on just the > conforming preprocessor (/Zc:preprocessor), without turning on C11 yet. > That way, we get that part out of the way, and we update the > documentation about requiring VS 2019. (And we'd flush out anyone who > might still be running pre-VS-2019 build jobs somewhere.) Later, when > we turn on C11, we can remove the explicit /Zc:preprocessor option again. > > (An alternative approach would be to turn on C11 and add another option > to explicitly turn the traditional preprocessor back on, but that seems > pointless, and the documentation also suggests that that combination is > not well supported.) > > So the attached patch is my proposal to commit early in PG19. I have committed this.