Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 转换为兼容返回类型的并集是否满足函数指针的兼容性标准?_C_Casting_Function Pointers_Unions_C89 - Fatal编程技术网

C 转换为兼容返回类型的并集是否满足函数指针的兼容性标准?

C 转换为兼容返回类型的并集是否满足函数指针的兼容性标准?,c,casting,function-pointers,unions,c89,C,Casting,Function Pointers,Unions,C89,为了解释我为什么要尝试这样做,环境的约束要求我使用自动生成的代码。生成的代码非常相似,我想调用一批基本相同的函数。我需要使用符合C89或C99的解决方案 从阅读规范来看,下面的代码似乎是合法的,但我不确定是否要强制转换函数指针以返回联合类型。有人能指出这是合法的还是违反了规范的哪一部分吗 #include <stdio.h> #include <stdlib.h> /* Automagically generated types */ struct A_return_

为了解释我为什么要尝试这样做,环境的约束要求我使用自动生成的代码。生成的代码非常相似,我想调用一批基本相同的函数。我需要使用符合C89或C99的解决方案

从阅读规范来看,下面的代码似乎是合法的,但我不确定是否要强制转换函数指针以返回联合类型。有人能指出这是合法的还是违反了规范的哪一部分吗

#include <stdio.h>
#include <stdlib.h>

/* Automagically generated types */

struct A_return_type {
    int index;
    unsigned int options;
};

struct A_return_type *A_function(int x) {
    struct A_return_type *A_return = malloc(sizeof(*A_return));
    A_return->index = x;
    A_return->options = 0xA;
    return A_return;
}

struct B_return_type {
    int index;
    unsigned int options;
};

struct B_return_type *B_function(int x) {
    struct B_return_type *B_return = malloc(sizeof(*B_return));
    B_return->index = x;
    B_return->options = 0xB;
    return B_return;
}

struct C_return_type {
    int index;
    unsigned int options;
};

struct C_return_type *C_function(int x) {
    struct C_return_type *C_return = malloc(sizeof(*C_return));
    C_return->index = x;
    C_return->options = 0xC;
    return C_return;
}

/* End generated types */

int main(int argc, char *argv[]) {
    /*--------------------------------------------------------------
    All of the generated methods take the same arguments and return
    structs with the same members in the same order. It is permitted
    to inspect the common initial part of any structs in a union,
    per C89 3.3.2.3 p5.
    --------------------------------------------------------------*/
    union return_types {
        struct {
            int index;
            unsigned int options;
        } common_return;
        struct A_return_type A_return;
        struct B_return_type B_return;
        struct C_return_type C_return;
    };

    /*----------------------------------------------------------
    Function pointers are compatible if their return types and
    parameter lists are compatible per C89 3.5.4.3 p9.
    ----------------------------------------------------------*/
    typedef union return_types *(*generated_function)(int);

    generated_function function_array[] = {
          (generated_function)A_function
        , (generated_function)B_function
        , (generated_function)C_function
    };

    for(int i = 0; i < sizeof(function_array)/sizeof(function_array[0]); ++i) {
        printf("%x\n", function_array[i](0)->common_return.options);
    }
}
#包括
#包括
/*自动生成的类型*/
结构A\u返回\u类型{
整数指数;
无符号整数选项;
};
结构A_返回类型*A_函数(int x){
结构A_return_type*A_return=malloc(sizeof(*A_return));
A_return->index=x;
A_return->options=0xA;
返回一个返回;
}
结构B_返回类型{
整数指数;
无符号整数选项;
};
结构B_返回类型*B_函数(int x){
结构B_return_type*B_return=malloc(sizeof(*B_return));
返回->索引=x;
返回->选项=0xB;
返回B_返回;
}
结构C_返回类型{
整数指数;
无符号整数选项;
};
结构C_返回类型*C_函数(int x){
结构C_return_type*C_return=malloc(sizeof(*C_return));
C_返回->索引=x;
C_return->options=0xC;
返回C_返回;
}
/*最终生成的类型*/
int main(int argc,char*argv[]){
/*--------------------------------------------------------------
所有生成的方法都采用相同的参数并返回
具有相同顺序的相同成员的结构。这是允许的
要检查联合体中任何结构的公共初始部分,
根据C89 3.3.2.3第5页。
--------------------------------------------------------------*/
联合返回类型{
结构{
整数指数;
无符号整数选项;
}共同收益;
结构A_返回类型A_返回;
结构B_返回类型B_返回;
结构C_返回类型C_返回;
};
/*----------------------------------------------------------
如果函数指针的返回类型和
参数列表与C89 3.5.4.3 p9兼容。
----------------------------------------------------------*/
typedef联合返回类型*(*生成的函数)(int);
生成的函数数组[]={
(生成的_函数)_函数
,(生成的_函数)B_函数
,(生成的_函数)C_函数
};
对于(int i=0;icommon\u return.options);
}
}

您可以将指向函数的指针转换为其他类型的指向函数的指针(C 2018 6.3.2.3 8:“指向一种类型函数的指针可能会转换为指向另一种类型函数的指针…”),但如果使用转换后的指针调用类型不兼容的函数,C标准没有定义行为(同上:“…如果使用转换的指针调用类型与引用类型不兼容的函数,则行为未定义。”)


返回
结构返回类型*
的函数与返回
联合返回类型*
的函数不兼容。6.2.5.28几乎可以节省您的时间,它说“…指向结构类型的所有指针应具有彼此相同的表示和对齐要求。指向联合类型的所有指针应具有彼此相同的表示和对齐要求…”,其中的脚注中写道相同的表示和对齐要求意味着作为函数参数、函数返回值和联合成员的互换性这种互换性意味着返回
struct foo*
的函数与返回
struct bar*
的函数兼容。不幸的是,您调用的函数返回指向结构的指针,而函数的表达式返回指向联合的指针,而标准并没有说明这两个函数具有相同的repre语句和对齐要求或它们是可互换的。

如果我强制转换函数以返回一个void*然后将其存储到联合中会怎么样?@JasonBrown:Standard C支持将字节从一个对象复制到另一个对象。您需要确保复制到联合中的字节对于使用联合的目的是有效的,即函数放入结构中的e字节与联合中要使用的字节相匹配。