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

杰森·布朗

为了解释为什么我要这样做,我的环境的约束要求我使用自动生成的代码。生成的代码非常相似,我想调用一批基本相同的函数。我需要使用符合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);
    }
}
埃里克·波斯蒂奇

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

返回astruct A_return_type *的函数与返回a的函数不兼容union return_types *您几乎被6.2.5 28所保存,它说“……所有指向结构类型的指针应具有相同的表示和对齐要求。所有指向并集类型的指针都必须具有相同的表示和对齐要求……”,并且在那里的脚注中说:“相同的表示和对齐要求旨在隐含作为函数的参数,函数的返回值以及并集的成员的互换性。 。” 这种可互换性意味着函数返回struct foo *与函数返回兼容struct bar *不幸的是,您正在调用一个返回指向结构的指针的函数,该函数带有一个返回指向联合的指针的函数的表达式,并且该标准并未说它们具有相同的表示和对齐要求,或者它们是可互换的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章