Simple question: shall a #pragma
leading to nonstandard behavior cause __STDC__
macro not to be defined to 1? (Does the C standard explicitly prescribes that? If yes, then in which section? If no, then why?) Reason of the question: see below.
Sample code (t28.c):
#pragma warning( disable : 34 )
typedef int T[];
int main()
{
int rc = sizeof(T);
#if __STDC__ == 1
rc = 0;
#else
rc = 1;
#endif
return rc;
}
Invocation: cl t28.c /std:c11 /Za && t28 ; echo $?
Expected result: 1
Actual result: 0
Compiler version:
cl
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29913 for x64
Note: C11 (6.5.3.4 The sizeof and _Alignof operators) (emphasis added):
The sizeof operator shall not be applied to an expression that has function type or an incomplete type, ...
Here we see that #pragma
leads to nonstandard behavior: "shall requirement" is violated, diagnostic message is not generated, compiler's backend is called, .exe
is produced and successfully executed. However, this nonstandard behavior does not cause __STDC__
macro not to be defined to 1
.
Reason of the question: tests. One test, similar to t28.c
is failing because it expects return code 1
(__STDC__
is not defined to 1
). Which part of the system contains the bug: test or compiler (or both)?
Here we see that
#pragma
leads to nonstandard behavior: "shall requirement" is violated, diagnostic message is not generated, compiler's backend is called,.exe
is produced and successfully executed. However, this nonstandard behavior does not cause__STDC__
macro not to be defined to 1.
First, the __STDC__
macro is not intended to be a mechanism for reporting “something happened during this compilation that resulted in nonstandard behavior.” It is not dynamic (changing) in that way. The desire for __STDC__
is simply for it to report that the C implementation is conforming. (It is only a desire because the C standard can require that conforming implementations define __STDC__
to be 1 but has no control over what nonconforming implementations define it to be.) If an implementation is conforming, __STDC__
will always be 1 regardless of what happens in any particular compilation.
(Note that one compiler may include multiple C implementations selected by various command-line switches, such as requesting different sizes for various types, enabling or disabling conforming extensions, enabling non-conforming variations from the C standard, and so on. Some combinations of switches may result in __STDC__
being defined to be 1 while others do not.)
Second, the #pragma warning( disable : 34 )
does not leading to nonstandard behavior. Per C 2018 6.10.6 1, this directive “causes the implementation to behave in an implementation-defined manner. The behavior might cause translation to fail or cause the translator or the resulting program to behave in [an otherwise] non-conforming manner.” So, supposing the pragma is documented by the implementation to suppress the warning about violation of the constraint in 6.5.3.4 1 about the sizeof
operator, then this is permitted by the C standard. This rule in 6.10.6 1 overrides the constraint in 6.5.3.4 1. The behavior is permitted by the C standard, so it is conforming.