gpt4 book ai didi

c - 将返回对象指针的函数强制转换为返回空指针的函数是否合法?

转载 作者:行者123 更新时间:2023-12-04 22:39:12 25 4
gpt4 key购买 nike

这些部分表明调用具有不兼容类型的函数指针会导致未定义的行为。

C89 3.5.4.3 p9

For two function types to be compatible, both shall specify compatible return types. Moreover, the parameter type lists, if both are present, shall agree in the number of parameters and in use of the ellipsis terminator; corresponding parameters shall have compatible types.

C89 3.5.4.1 p2

For two pointer types to be compatible, both shall be identically qualified and both shall be pointers to compatible types.

C89 3.3.4 p3

A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function that has a type that is not compatible with the type of the called function, the behavior is undefined.


从任何其他对象指针类型转换为 void 指针是否兼容?

C89 3.3.4 p3

It is guaranteed, however, that a pointer to an object of a given alignment may be converted to a pointer to an object of the same alignment or a less strict alignment and back again; the result shall compare equal to the original pointer. (An object that has character type has the least strict alignment.)

C89 3.1.2.5 p20

A pointer to void shall have the same representation and alignment requirements as a pointer to a character type.

C89 3.2.2.3 p1

A pointer to void may be converted to or from a pointer to any incomplete or object type. A pointer to any incomplete or object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.


例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int *foo(void) {
int *data = malloc(sizeof(int));
*data = 42;
return data;
}

int main(int argc, char *argv[]) {
void *(*fn_ptr)(void) = foo;
void *raw = fn_ptr();
int data = *(int *)raw;
printf("%d\n", data);
}

最佳答案

您询问将指向函数的指针转换为指向函数的另一个指针是否合法。将指向函数的指针强制转换为指向函数的任何其他指针是合法的。但是通过这样的指针调用函数会调用未定义的行为。 C11 6.5.2.2p9

6.5.2.2 Function calls

[...]

  1. If the function is defined with a type that is not compatible with the type (of the expression) pointed to by the expression that denotes the called function, the behavior is undefined.

另一个问题是您的代码没有强制转换。它有一个强制赋值:
void *(*fn_ptr)(void) = foo;
这是无效的,具有约束冲突,C 编译器必须诊断。 Actor 会读
void *(*fn_ptr)(void) = (void *(*)(void))foo;

现在的问题是什么是行为
void *(*fn_ptr)(void) = (void *(*)(void))foo;
void *raw = fn_ptr();
int data = *(int *)raw;
根据标准,该构造的行为未定义。当然,您的实现可以自由地为表达式提供含义。在这种情况下,您应该检查编译器手册中的行为。
已经存在表示 void * 的架构。和 int *不会兼容。

如果您只是将函数指针更改为返回 int * 的函数指针或在调用之前回滚,行为是明确定义的 - 隐式转换为 void *并显式转换为 int *都很好。
IE。
int *(*fn_ptr)(void) = foo;
void *raw = fn_ptr();
int data = *(int *)raw;
或者
void *(*fn_ptr)(void) = (void *(*)(void))foo;
void *raw = ((int *(*)(void))fn_ptr)();
int data = *(int *)raw;

或者让函数返回 void * :
void *foo(void) {
int *data = malloc(sizeof(int));
*data = 42;
return data;
}

void *(*fn_ptr)(void) = foo;
void *raw = fn_ptr();
int data = *(int *)raw;

关于c - 将返回对象指针的函数强制转换为返回空指针的函数是否合法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58548331/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com