每个C标准中带空括号的函数指针的含义是什么? [英] What are the semantics of function pointers with empty parentheses in each C standard?

查看:106
本文介绍了每个C标准中带空括号的函数指针的含义是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

回答这个问题说,形式为 return-type(* pointer)()的函数指针是指向带有任意数量参数的函数的指针,尽管后者表示它们在C11中已作废

Answers to this and this question say that function pointers of the form return-type (*pointer)() are pointers to a function which takes any number of arguments, though the latter says they obsolesced in C11.

在具有GCC的i386系统上,额外"由于堆栈帧的工作方式,在调用中传递给空括号类型d函数指针的参数将被忽略.例如,

On an i386 system with GCC, “extra” arguments passed in a call to an empty-parentheses-type’d function pointer are ignored, because of how stack frames work; e.g.,

/* test.c */
#include <stdio.h>

int foo(int arg) { return arg; }

int main(void)
{
    int (*fp)() = foo;
    printf("%d\n", fp(267239151, 42, (struct { int x, y, z; }){ 1, 2, 3 }));
    return 0;
}

$ gcc -o test test.c && ./test
267239151
$ 

在哪些C标准中允许使用空括号d函数指针?而无论在哪里,它们的指定含义是什么?

In which C standards are empty-parentheses’d function pointers allowed? and wherever so, what are they specified to mean?

推荐答案

N1570 6.11.6:

带空括号的函数声明符的使用(不是原型格式参数类型声明符)是过时的功能.

The use of function declarators with empty parentheses (not prototype-format parameter type declarators) is an obsolescent feature.

同一措辞出现在1990年,1999年和2011年的ISO C标准中.没有变化. obsolescent 一词表示该功能可能会在该标准的未来版本中删除,但到目前为止,委员会尚未这样做.(函数指针声明只是可以出现函数声明符的几种上下文之一.)

This same wording appears in the 1990, 1999, and 2011 editions of the ISO C standard. There has been no change. The word obsolescent says that the feature may be removed in a future edition of the Standard, but so far the committee has not done so. (Function pointer declarations are just one of several contexts where function declarators can appear.)

C标准的简介"部分解释了过时的含义:

The Introduction section of the C standard explains what obsolescent means:

某些功能已经过时,这意味着它们可能是考虑在本国际日后的修订版中撤回标准.由于它们的广泛使用而被保留,但是它们用于新的实现(用于实现功能)或新的程序(对于语言[6.11]或库功能[7.31])是灰心丧气.

Certain features are obsolescent, which means that they may be considered for withdrawal in future revisions of this International Standard. They are retained because of their widespread use, but their use in new implementations (for implementation features) or new programs (for language [6.11] or library features [7.31]) is discouraged.

仍然需要调用使用旧式声明程序声明的函数,以传递由函数的实际定义定义的正确数量和类型的参数(升级后).具有错误参数的调用具有未定义的行为,这意味着不需要编译器来诊断错误.负担完全在程序员身上.

A call to a function declared with an old-style declarator is still required to pass the correct number and type(s) of arguments (after promotion) as defined by the function's actual definition. A call with incorrect arguments has undefined behavior, which means that the compiler is not required to diagnose the error; the burden is entirely on the programmer.

这就是引入原型的原因,以便编译器可以检查参数的正确性.

This is why prototypes were introduced, so that the compiler could check correctness of arguments.

在具有GCC的i386系统上,额外"参数在调用中传递给空括号类型的函数指针将被忽略,因为堆栈框架可以工作...

On an i386 system with GCC, "extra" arguments passed in a call to an empty-parentheses-type’d function pointer are ignored, because of how stack frames work ...

是的,这完全在未定义行为的范围之内.未定义行为的最严重症状是使程序完全按照您期望的方式工作.这意味着您有一个还没有出现的错误,并且很难找到它.

Yes, that's well within the bounds of undefined behavior. The worst symptom of undefined behavior is having the program work exactly as you expect it to. It means that you have a bug that hasn't exhibited itself yet, and it will be difficult to track it down.

除非您有非常个充分的理由这样做,否则您不应依赖它.

You should not depend on that unless you have a very good reason to do so.

如果您更改

int (*fp)() = foo;

int (*fp)(int) = foo;

编译器将诊断出错误的调用.

the compiler will diagnose the incorrect call.

这篇关于每个C标准中带空括号的函数指针的含义是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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