标准库函数定义为宏的参数类型错误 [英] Wrong argument type to a standard library function defined as macro

查看:140
本文介绍了标准库函数定义为宏的参数类型错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是示例代码:

#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?

动机:即使是一致的代码,也没有多个主要的编译器对此代码发出警告. C11 6.5.2.2/2涵盖了将char *传递给原型期望为int的函数是违反约束的情况.

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.

但是,我不清楚7.1.4中允许将库函数另外定义为宏的规定是否取代了6.5.2.2/2的要求.脚注187表明该宏隐藏了原型,但脚注是非规范性的.

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.

代码(isalpha)("X");确实可以提供诊断信息.

The code (isalpha)("X"); does give a diagnostic of course.

推荐答案

我认为这里的关键是是否允许将isalpha定义为宏. C11 7.1.4简要提及

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

尽管本章主要涉及命名冲突和多线程问题等.另一方面,C11 7.4表示:

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.

和C11 7.4.1.2:

and C11 7.4.1.2:

int isalpha(int c);

isalpha 函数...

我认为isalpha被视为一个函数.或者,如果实现为宏,则必须通过某种实现来确保某种类型的类型检查.

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.

鉴于它是一个函数,因此从那里很明显.对于所有函数,函数调用规则在C11 6.5.2.2中指定:

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.

请注意好像是通过分配"部分.这使我们找到了简单分配C11 6.5.16.1约束的规则.问题中的代码将在行后等同于赋值表达式,例如int c = (char[]){"X"};,其中左操作数是算术类型,右操作数是指针.在C11 6.5.16.1中的任何地方都找不到这种情况.

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.

因此,该代码违反了6.5.16.1的约束.

Therefore the code is a constraint violation of 6.5.16.1.

如果编译器库选择将isalpha实现为宏,从而由于在赋值期间不执行函数参数的常规左值转换而以某种方式失去了类型检查功能,则该库很可能是不合格的,如果编译器无法生成诊断消息.

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.

这篇关于标准库函数定义为宏的参数类型错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆