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 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 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