Dear maintainers, 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. We've defined CC=cl. I'm having problems running `AC_PROG_CC`. I'd like to teach it to discover the required options to build my code in C11, so that the tests automatically pick the right options. > checking for cl.exe option to enable C11 features... unsupported 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 ]) I've found two problems. MSVC doesn't enable the `__STDC__` macro by default, it needs a `/Zc:__STDC__` flag [3]. This is done to prevent compatibility issues [4]. > The C++ standard reserves names that begin with an underscore in the > global namespace to the implementation. Both the POSIX functions and > Microsoft-specific runtime library functions are in the global > namespace, but aren't part of the standard C runtime library. It's > why the preferred Microsoft implementations of these functions have > a leading underscore. They have a strict reading of the standard at _6.10.8.1 Mandatory macros_: > `__STDC__` The integer constant `1`, intended to indicate a > conforming implementation. The default test program for C11 includes `_AC_C_C89_TEST_GLOBALS`, which has: /* Does the compiler advertise C89 conformance? Do not test the value of __STDC__, because some compilers set it to 0 while being otherwise adequately conformant. */ #if !defined __STDC__ # error "Compiler does not advertise C89 conformance" #endif 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. Although (probably) no header file is going to be broken with this check (but you never know with Microsoft), it sounds to me like a warning against the Zc flag. 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? 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. Should the test for VLAs be removed, or guarded by the macro, even if the macro is C11 and the test is C99? There's indeed the `AC_C_VARARRAYS` test, but I think there's a chicken-and-egg problem here if it also requires `AC_PROG_CC`. More generally, it seems odd that the C11 "conformance" test includes tests for all previous revisions of the C standard. I've hacked the configure script for testing, and these are the only two issues that would make Autoconf enable C11 for MSVC out of the box. [1]: https://github.com/ocaml/ [2]: https://devblogs.microsoft.com/cppblog/c11-and-c17-standard-support-arriving-in-msvc/ [3]: https://learn.microsoft.com/en-us/cpp/build/reference/zc-stdc?view=msvc-170 [4]: https://learn.microsoft.com/en-us/cpp/c-runtime-library/compatibility?view=msvc-170 [5]: https://en.wikipedia.org/wiki/Variable-length_array Best regards, -- Antonin