本文介绍了函数指针算法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么这段代码能正确编译函数指针的算术运算?

Why is this code compiling correctly for the arithmetic on a function pointer?

void my_func(void);

int main(void)
{
    void (*p)(void) = &my_func;

    // Compile
    (void) (*p);
    (void) *(p + 0);

    // Does not compile
    (void) p[0];

    return 0;
}

我一直认为 p[0] == *(p + 0) 对于完整类型.显然,p[0] != *(p + 0) 用于函数指针.

I have always thought that p[0] == *(p + 0) for complete types. Apparently, p[0] != *(p + 0) for function pointers.

注意:C 标准没有明确禁止函数指针算术.它根本不禁止它.它说它是未定义的.那是另一回事.许多符合标准条款的语言扩展具有标准未定义的行为.

Note: the C standard does not explicitly forbid function pointer arithmetic. It does not forbid it at all. It says it is undefined. That is a different thing. Many language extensions that are conforming in the terms of the standard have behavior that is undefined by the standard.

此外,如果您使用指向不完整类型的指针,那么我们有:

Also, if you use a pointer to an incomplete type, then we have:

int main(void)
{
    int (*p)[];

    // Compile
    (void) (*p);

    // Does not compile
    (void) *(p + 0);
    (void) p[0];

    return 0;
}

然后有效地p[0] == *(p + 0) 因为对于指向不完整类型的指针的算术运算,两者都会触发相同的错误.尽管在这里,C 标准明确禁止对指向不完整类型的指针进行算术运算.

Then effectively p[0] == *(p + 0) because both triggers the same error for arithmetic on an pointer to an incomplete type. Although here, the C standard does explicitly forbid arithmetic on an pointer to an incomplete type.

推荐答案

数组下标 a[b] 需要 ab 之一成为指向完整对象类型的指针.函数类型不是完整的对象类型.

Array subscripting a[b] needs one of a or b to be a pointer to a complete object type. A function type is not a complete object type.

6.5.2.1 数组下标

约束

1 其中一个表达式的类型应为指向完整对象类型的指针",另一个表达式应为整数类型,结果类型为类型".

1 One of the expressions shall have type "pointer to complete object type", the other expression shall have integer type, and the result has type "type".

请注意,p + 0 也应该是出于相同原因的错误,我相信编译器无法生成所需的诊断消息.我问这个为什么不生产:当程序对函数指针进行指针运算时,clang 和 gcc 是否应该产生诊断消息?

Note that p + 0 should also be an error for the same reason, and I believe the compiler is failing to produce a required diagnostic message. I asked this about why it's not produced: Should clang and gcc produce a diagnostic message when a program does pointer arithmetic on a function pointer?

6.5.6 加法运算符

约束

对于加法,要么两个操作数都具有算术类型,要么一个操作数应该是一个指向完整对象类型的指针,另一个应为整数类型.(递增相当于加1.)

For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to a complete object type and the other shall have integer type. (Incrementing is equivalent to adding 1.)

这篇关于函数指针算法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-16 07:13