Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default to C11 standard and missing __STDC_NO_THREADS__ ( windows) #48048

Closed
P-p-H-d opened this issue Jan 10, 2021 · 7 comments
Closed

Default to C11 standard and missing __STDC_NO_THREADS__ ( windows) #48048

P-p-H-d opened this issue Jan 10, 2021 · 7 comments
Labels
bugzilla Issues migrated from bugzilla c

Comments

@P-p-H-d
Copy link

P-p-H-d commented Jan 10, 2021

Bugzilla Link 48704
Version 11.0
OS Windows XP
CC @AaronBallman,@DougGregor,@zmodem,@nico,@zygoloid,@rnk

Extended Description

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?

@rnk
Copy link
Collaborator

rnk commented Jan 11, 2021

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.

@P-p-H-d
Copy link
Author

P-p-H-d commented Jan 11, 2021

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.

@AaronBallman
Copy link
Collaborator

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.

@P-p-H-d
Copy link
Author

P-p-H-d commented Oct 17, 2021

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?

@AaronBallman
Copy link
Collaborator

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.

@zmodem
Copy link
Collaborator

zmodem commented Oct 19, 2021

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

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 11, 2021
@zmodem
Copy link
Collaborator

zmodem commented Dec 16, 2021

@zmodem zmodem closed this as completed Dec 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla c
Projects
None yet
Development

No branches or pull requests

4 participants