Here is sample code:
#include <ctype.h>
int main(void)
{
isalpha("X");
}
My question is: Is this code a constraint violation? Equivalently, is an implementation non-conforming if it does not issue a diagnostic?
Motivation: Multiple major compilers don't warn for this code, even in conforming code. C11 6.5.2.2/2 covers that passing char *
to a function with prototype expecting int
is a constraint violation.
However it is not clear to me whether the provisions in 7.1.4 allowing a library function to be additionally defined as a macro supersede the requirement of 6.5.2.2/2. Footnote 187 suggests that the macro hides the prototype, but footnotes are non-normative.
The code (isalpha)("X");
does give a diagnostic of course.
I think the key here is whether isalpha
is allowed to be defined as a macro or not. C11 7.1.4 briefly mentions
Any function declared in a header may be additionally implemented as a function-like macro defined in the header
although this chapter is mostly concerned with naming collisions and multi-threading issues etc. On the other hand, C11 7.4 says:
The header declares several functions useful for classifying and mapping characters.
and C11 7.4.1.2:
int isalpha(int c);
The isalpha function...
My take is that isalpha
is to be regarded as a function. Or if implemented as a macro, some manner of type check must be ensured by the implementation.
Given that it is a function, it is pretty clear from there. For all functions, the rules for function call are specified in C11 6.5.2.2:
If the expression that denotes the called function has a type that does include a prototype, the arguments are implicitly converted, as if by assignment, to the types of the corresponding parameters, taking the type of each parameter to be the unqualified version of its declared type.
Note the "as if by assignment" part. This leads us to the rules for simple assignment C11 6.5.16.1, constraints. The code in the question would behind the lines be equivalent to an assignment expression such as int c = (char[]){"X"};
where the left operand is an arithmetic type and the right operand is a pointer. No such case can be found anywhere in C11 6.5.16.1.
Therefore the code is a constraint violation of 6.5.16.1.
If a compiler lib chooses to implement isalpha
as a macro and thereby loses the type check ability somehow by not performing the normal lvalue conversion of function parameters during assignment, then that library might very well be non-conforming, if the compiler fails to produce a diagnostic message.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With