Since the switch to default to C11, compliant program fails to build **by default** (without forcing another mode) on windows: #if defined(__STDC_VERSION__) && \ (__STDC_VERSION__ >= 201102L) && \ !defined(__STDC_NO_THREADS__) # include <threads.h> #endif [ build with only "clang.exe -c test.c" ] It is probably the same for other predefined macros. This may be a library issue, but is it ok to default to C11 if there is known library issue for such support?
Well, there is always __has_include(<threads.h>). Do you think that defining __STDC_NO_THREADS__ is a promise that there cannot be threads in a program? As a programmer, a "no threads" macro seems like something that would be used to turn off expensive library synchronization. In that case, I don't think the compiler can define this macro on Windows, because there are threads on Windows, it's just the library support which may be missing. One day maybe Visual C++ will provide threads.h, so the most we can do is do the __has_include test internally in the compiler to power this macro.
> Do you think that defining __STDC_NO_THREADS__ is a promise that there cannot be threads in a program? No. Defining __STDC_NO_THREADS__ indicates that the implementation does not support the <threads.h> header (cf. ยง6.10.8.3 of C11) __STDC_NO_ATOMICS__ & __STDC_NO_COMPLEX__ are probably also missing.
> One day maybe Visual C++ will provide threads.h, so the most we can do is do the __has_include test internally in the compiler to power this macro. We really can't even do that much because 7.26.1p2 says: "Implementations that define the macro __STDC_NO_THREADS__ need not provide this header nor support any of its facilities." Note how it doesn't say implementations that define the macro to a particular value, just whether implementations define the macro at all. The trouble is: Clang doesn't ship the full C implementation, it only ships the compiler and the library portions that need to come from the compiler, which does not include <threads.h>. We rely on the target platform to provide the rest of the C standard library interfaces, so the compiler doesn't know whether to define the macro or not. Some versions of glibc support <threads.h> and some do not, no version of MSVC CRT supports <threads.h> currently, etc. Users have to rely on the C standard library implementation to provide this macro or not.
Then shouldn't clang-cl (not clang) switch back to C99 (or C89) for the default language mode as clang-cl is only for MSVC CRT?
(In reply to PpHd from comment #4) > Then shouldn't clang-cl (not clang) switch back to C99 (or C89) for the > default language mode as clang-cl is only for MSVC CRT? clang-cl is a drop-in replacement for cl.exe, so it should default to whatever default language mode is claimed by cl.exe. From my testing: c:\Users\aballman\OneDrive - Intel Corporation\Desktop>cat test.c int main(void) { return __STDC_VERSION__; } c:\Users\aballman\OneDrive - Intel Corporation\Desktop>cl test.c Microsoft (R) C/C++ Optimizing Compiler Version 19.29.30133 for x64 Copyright (C) Microsoft Corporation. All rights reserved. test.c test.c(2): error C2065: '__STDC_VERSION__': undeclared identifier c:\Users\aballman\OneDrive - Intel Corporation\Desktop>cl test.c /std:c11 Microsoft (R) C/C++ Optimizing Compiler Version 19.29.30133 for x64 Copyright (C) Microsoft Corporation. All rights reserved. test.c Microsoft (R) Incremental Linker Version 14.29.30133.0 Copyright (C) Microsoft Corporation. All rights reserved. /out:test.exe test.obj c:\Users\aballman\OneDrive - Intel Corporation\Desktop>test.exe c:\Users\aballman\OneDrive - Intel Corporation\Desktop>echo %errorlevel% 201112 c:\Users\aballman\OneDrive - Intel Corporation\Desktop>cl test.c /std:c17 Microsoft (R) C/C++ Optimizing Compiler Version 19.29.30133 for x64 Copyright (C) Microsoft Corporation. All rights reserved. test.c Microsoft (R) Incremental Linker Version 14.29.30133.0 Copyright (C) Microsoft Corporation. All rights reserved. /out:test.exe test.obj c:\Users\aballman\OneDrive - Intel Corporation\Desktop>test.exe c:\Users\aballman\OneDrive - Intel Corporation\Desktop>echo %errorlevel% 201710 So it seems as though cl doesn't set __STDC_VERSION__ at all by default unless you pass a command line flag to it. I don't know if we want to emulate that behavior or not (my inclination is that we should emulate it, but I don't use clang-cl myself). Then I checked to see if maybe they do the same shenanigans with __STDC_NO_THREADS__: c:\Users\aballman\OneDrive - Intel Corporation\Desktop>cat test.c int main(void) { return __STDC_NO_THREADS__; } c:\Users\aballman\OneDrive - Intel Corporation\Desktop>cl test.c Microsoft (R) C/C++ Optimizing Compiler Version 19.29.30133 for x64 Copyright (C) Microsoft Corporation. All rights reserved. test.c test.c(2): error C2065: '__STDC_NO_THREADS__': undeclared identifier c:\Users\aballman\OneDrive - Intel Corporation\Desktop>cl test.c /std:c11 Microsoft (R) C/C++ Optimizing Compiler Version 19.29.30133 for x64 Copyright (C) Microsoft Corporation. All rights reserved. test.c Microsoft (R) Incremental Linker Version 14.29.30133.0 Copyright (C) Microsoft Corporation. All rights reserved. /out:test.exe test.obj c:\Users\aballman\OneDrive - Intel Corporation\Desktop>test.exe c:\Users\aballman\OneDrive - Intel Corporation\Desktop>echo %errorlevel% 1 So it looks like Microsoft does define __STDC_NO_THREADS__ but only when explicitly set to C11 or C17 mode, and not when compiling for C in general. This behavior makes no sense to me, because Microsoft does not support threads.h in older language modes and this macro is a reserved identifier so they're free to define it in any language mode where it makes sense. Adding some clang-cl folks to weigh in with their thoughts.
> So it seems as though cl doesn't set __STDC_VERSION__ at all by default unless you pass a command line flag to it. I don't know if we want to emulate that behavior or not (my inclination is that we should emulate it, but I don't use clang-cl myself). Hmm, similar to __STDC__ I guess, which they don't set unless /Za is passed according to the docs. As for __STDC_NO_THREADS__, it's true that since clang doesn't provide the standard library it can't really answer the question of whether threads.h exists, but it does know if it's targeting an "msvc environment", and could perhaps set the macro based on that. Something like: https://reviews.llvm.org/D112081