如果改变编译器,是否将结构指针解引用为不同结构的指针会改变输出?

时间:2014-01-10 11:48:49

标签: c pointers struct dereference

在以下伪代码中:

#include<stdio.h>
typedef struct _apple
{
    int a;
    char b;
    float c;
} apple;

typedef struct _orange
{
    int a;
    int b;
} orange;

typedef struct _grape
{
    int a;
} grape;

void main()
{
    apple a1;
    orange o1;

    a1.a =1;
    a1.b =2;
    a1.c =3;
    o1.a =4;

    void * fruit[] = {&a1, &o1};

    grape *app = (grape*)fruit[0];

    printf ("\nRead: %d    ", app->a);
    app = (grape*)fruit[1];

    printf ("\nRead: %d    ", app->a);
}

结构葡萄是苹果和橙子的一个子集,因为它含有与苹果和橙色相同的元素。该程序将预期输出提供为1和4.但是这种方法是否有可能因不同的编译器或任何其他特定于环境的更改而失败?

2 个答案:

答案 0 :(得分:1)

您可以使用union来处理所有类型:

typedef struct {
    /* Common elements */
    int a;
    /* Type specific */
    union {
        struct {
            char b;
            float c;
        } apple;
        struct {
            int b;
        } orange;
    } special;
} fruit;

fruit or;
or.a = 1;
or.special.orange.b = 2;
fruit * f = &or;

或模仿对象继承:

/* Common elements (base class) */
typedef struct {
    int a;
} fruit;

/* Extended types */
typedef struct {
    fruit parent; /* Must be first */
} grape;

typedef struct {
    fruit parent; /* Must be first */
    int b;
} orange;

orange or;
or.parent.a = 1;
or.b = 2;
fruit * f1 = (fruit*)&or;
fruit * f2 = &or.parent; /* alternate type safe way */

或者使用C ++来获得正确的继承。

答案 1 :(得分:0)

如果您知道指针指向指针未指示的内容,则应该投射任何内容。但是当你假设编译器以特定的方式编译某些内容时,你永远不应该进行投射。

当任何结构元素发生变化时,您的方法将失败。它违反了可维护性的要求。您的方法可能会因任何新的编译器变体而失败。