On Tue, Apr 23, 2024 at 09:07:49PM -0300, Antonin Décimo wrote: > I'm hacking on the Autoconf scripts for the OCaml compiler [1]. I'm > trying to make them more useful when compiling with the dreaded MSVC. Thanks for tackling this! > MSVC has supported C11 and C17 since September 2020 [2]. The options > to enable support are `/std:c11` and `/std:c17`. There's an > alternative syntax, `-std:c11` and `-std:c17` (dash instead of slash). > > diff --git a/lib/autoconf/c.m4 b/lib/autoconf/c.m4 > index d8eab7bb..01d4cfa6 100644 > --- a/lib/autoconf/c.m4 > +++ b/lib/autoconf/c.m4 > @@ -1553,6 +1553,7 @@ m4_define([_AC_C_C99_OPTIONS], [ > # shell quotes around the group. > # > # GCC, Clang -std=gnu11 > +# MSVC -std:c11 > # > # For IBM XL C for AIX V16.1 or later, '-std=gnu11' should work if > # the user configured with CC='xlclang'. Otherwise, do not try > @@ -1562,6 +1563,7 @@ m4_define([_AC_C_C99_OPTIONS], [ > # _Noreturn, which is a win. > m4_define([_AC_C_C11_OPTIONS], [ > -std=gnu11 > + -std:c11 > ]) This change looks correct to me in isolation, and I concur with using the dash-prefix form for the reasons you stated in your other message. > MSVC doesn't enable the `__STDC__` macro by default, it needs a > `/Zc:__STDC__` flag [3]. This is done to prevent compatibility issues [4]. ... > MSVC fails this check. I'm tempted to add the `/Zc:__STDC__` flag to > `_AC_C_C11_OPTIONS`, however its doc reads: > > > Do not try "strictly conforming" modes (e.g. gcc's -std=c11); they > > break some systems' header files. ... > Should both `/std:c11 /Zc:__STDC__` be added to `_AC_C_C11_OPTIONS` to > support MSVC? Should Autoconf remove the `__STDC__` check or check for > MSVC at this stage? This is a hard one. I haven't done much programming for Windows at all, but I have had to work with other systems that had more-or-less ISO-C89-conformant compilers and C runtimes but didn't define __STDC__, for more or less the same reason Microsoft isn't defining it -- they didn't want to claim conformance outside of a "strict conformance" mode that caused more problems than it solved. In the 1990s and early 2000s, it was very common to see #ifdef __STDC__ or #if __STDC__ in application code, for example using it to decide whether to use prototyped or old-style function definitions. That code would, in the worst case, fail to compile on the systems I'm thinking of, because *both* modes were wrong -- with __STDC__ not defined, they would use the "K&R compiler" side of the ifdefs and do things like preprocessor token concatenation the wrong way; with __STDC__ defined, the C library was in "strict" mode and missing important declarations from the headers. Nowadays, preprocessor conditionals on __STDC__ are less common, but I am still worried that both possibilities are wrong: with /Zc:__STDC__ Microsoft's compilers will make <fcntl.h> not declare open(), breaking application code; without it, application code may assume that it's dealing with a "K&R" compiler. I think we need input here from an expert on low-level C programming and portability issues specifically for Windows. If anyone reading this has those qualifications, please speak up. I will try to find someone through other means if nobody speaks up in a week or two. (The comment about "strictly conforming" modes breaking system headers was motivated by a related problem: on some systems, the code *inside* important headers like <netinet/in.h> will throw compile errors if you feed it to GCC in -std=cXX mode, because it's never been tested that way. However, that comment is definitely *relevant*. If the preprocessor macro under discussion was anything but __STDC__ or __STDC_VERSION__ I would say "no, don't use that option here" without hesitation, but...) (Can you check if there's maybe some way to make the UCRT declare POSIX functions like open(), without a leading underscore, *even if* __STDC__ is defined? Another macro that you define, maybe?) > The second problem is that MSVC has no support for Variable-Length > Arrays (VLA) [5]. There is however a test for VLAs in > `_AC_C_C99_TEST_MAIN`. C11 has introduced in _6.10.8.3 Conditional > feature macros_: > > > `__STDC_NO_VLA__` The integer constant `1`, intended to indicate > > that the implementation does not support variable length arrays or > > variably modified types. > > However the VLA test is included as-is in the C11 main program, but > C11 made that feature optional. MSVC correctly defines the > `__STDC_NO_VLA__` macro, but fails the Autoconf test. This is clearly > an Autoconf bug, but the fix isn't clear. I think what we should do here is fold AC_C_VARARRAYS into AC_PROG_CC. Take the test for VLAs completely out of _AC_C_C99_TEST_MAIN, but unconditionally *run* a test for VLAs as part of AC_PROG_CC. If that test fails, and __STDC_NO_VLA__ was not defined by the compiler, then AC_DEFINE([__STDC_NO_VLA__], 1) and set a cache variable. Mark AC_C_VARARRAYS as obsolete (i.e. AU_DEFUN it) and have it just check the cache variable and AC_DEFINE(HAVE_C_VARARRAYS), with post-autoupdate diagnostics telling the reader to replace HAVE_C_VARARRAYS with !__STDC_NO_VLA__ and then remove the compatibility code. Do you know how to do all of that? I can do it (not for another couple of weeks) if it sounds too daunting, but I will need you to test it for me as I don't have convenient access to a compiler that doesn't support VLAs. zw