Making MSVC/clang-cl succeed AC_PROG_CC C11 discovery

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [GCC Help]     [Kernel Discussion]     [RPM Discussion]     [Red Hat Development]     [Yosemite News]     [Linux USB]     [Samba]

  Powered by Linux