相关疑难解决方法(0)

什么是严格别名规则?

当询问C中常见的未定义行为时,灵魂比我提到的严格别名规则更加开明.
他们在说什么?

c strict-aliasing undefined-behavior type-punning

778
推荐指数
10
解决办法
19万
查看次数

gcc,严格别名,并通过联合进行转换

你有任何恐怖故事要讲吗?GCC手册最近添加了一个关于-fstrict-aliasing的警告并通过联合转换指针:

[...]获取地址,强制生成指针并取消引用结果具有未定义的行为 [强调添加],即使转换使用了联合类型,例如:

    union a_union {
        int i;
        double d;
    };

    int f() {
        double d = 3.0;
        return ((union a_union *)&d)->i;
    }
Run Code Online (Sandbox Code Playgroud)

有没有人有一个例子来说明这种未定义的行为?

请注意,这个问题不是关于C99标准所说或不说的.它是关于gcc和其他现有编译器的实际功能.

我只是猜测,但一个潜在的问题可能在于设置d为3.0.因为d是永远不会直接读取的临时变量,并且永远不会通过"稍微兼容"的指针读取,所以编译器可能不会费心去设置它.然后f()将从堆栈中返回一些垃圾.

我的简单,天真,尝试失败了.例如:

#include <stdio.h>

union a_union {
    int i;
    double d;
};

int f1(void) {
    union a_union t;
    t.d = 3333333.0;
    return t.i; // gcc manual: 'type-punning is allowed, provided...' (C90 6.3.2.3)
}

int f2(void) {
    double d = 3333333.0;
    return ((union a_union *)&d)->i; // gcc …
Run Code Online (Sandbox Code Playgroud)

c gcc type-conversion strict-aliasing unions

34
推荐指数
3
解决办法
1万
查看次数

使用C语言中的结构联合

说我有以下类型:

typedef struct TYPEA
{
    int type;
    char[12] id;
} TYPEA;

typedef struct TYPEB
{
    int type;
    int value;
} TYPEB;
Run Code Online (Sandbox Code Playgroud)

我想使用创建这些类型和'int'的联合,这样我就可以访问"type"int而无需知道TYPEA或TYPEB是否存储在union中(int的值让我确定实际存储的是哪个那里).虽然我无法获得正确的语法.

我的工会:

typedef union MEMBER
{
    int type;
    struct TYPEA a;
    struct TYPEB b;
} MEMBER;
Run Code Online (Sandbox Code Playgroud)

通过以下方式访问联盟:

typedef struct WRAPPER
{
    union MEMBER* member;
    struct WRAPPER* next;
} WRAPPER;
Run Code Online (Sandbox Code Playgroud)

问题:

  1. (使用'w'作为指向已分配的WRAPPER结构的指针)访问使用w->member->a.id会在某些结构或联合中提供"成员'id'请求.
  2. 我可以直接将指向已经malloc的TYPEA/B的指针分配给w->成员吗?或者工会是否需要专门进行malloced?

谢谢.

c unions

6
推荐指数
1
解决办法
3万
查看次数