当前位置: 首页 > 知识库问答 >
问题:

在不破坏C99中严格的混淆现象规则的情况下,使用void*键入双关语

欧阳飞章
2023-03-14

我最近遇到了严格的别名规则,但我很难理解如何使用 void * 在不违反规则的情况下执行类型双关。

我知道这违反了规定:

int x = 0xDEADBEEF;

short *y = (short *)&x;
*y = 42;

int z = x;

我知道我可以安全地使用C99中的联合进行打字双关语:

union{
    int x;
    short y;
} data;

data.x = 0xDEADBEEF;
data.y = 42;

int z = data.x;

但是,我如何使用 void * 在 C99 中安全地执行类型双关语?以下是否正确:

int x = 0xDEADBEEF;

void * helper = (void *)&x;

short *y = (short *)helper;
*y = 42;

int z = x;

我怀疑代码仍然会违反严格的别名规则,因为变量< code>x地址处的内存可以被< code>x和一个解引用的< code>y修改。

如果通过< code>void *没有定义类型双关,那么C99中的< code>void *的目的是什么?

共有1个答案

楚宏胜
2023-03-14

void * 与类型双关无关。其主要目的是:

>

  • 允许泛型分配和释放不关心调用者存储在那里的对象类型的操作(例如mallocfree)。

    允许调用者通过一个函数传递一个指向任意类型的指针,该函数将通过一个回调把它传递回来,(例如< code>qsort和< code>pthread_create)。在这种情况下,编译器不能强制类型检查;编写调用者和回调函数时,您有责任确保回调函数以正确的类型访问对象。

    指向void的指针也用于一些地方(如memcpy>),这些地方实际上作为对象的覆盖 char类型可以对任何内容进行别名以访问其表示。在这种情况下, unsigned char*也可以工作,但 void*具有指针自动转换为

    在您的示例中,由于原始类型是< code>int而不是union,因此没有合法的方法来进行类型转换并将其作为< code>short进行访问。相反,您可以将< code>x的值复制到一个联合中,在那里执行定义良好的类型双关,然后将其复制回来。一个好的编译器应该完全省略副本。或者,您可以将写操作分解为< code>char写操作,然后这将是合法的别名。

  •  类似资料:
    • 在这些注释中,user @Deduplicator坚持认为,如果别名指针或别名指针是指向字符的指针类型(限定或非限定,有符号或无符号< code>char *),则严格的别名规则允许通过不兼容的类型进行访问。所以,他的观点基本上是 和 符合并具有定义的行为。 然而,在我看来,只有第一种形式是有效的,即当别名指针是指向char的指针时;然而,在另一个方向上却不能,即当别名指针指向不兼容的类型(而不是

    • 下面的getValue()成员函数是否违反了c严格别名规则? 根据该标准,我认为setValue()违反了严格的混淆现象,因为Double既不是聚合类型,也不是IEEE754_64的基类。 getValue()呢?当数据成员采用位字段形式时,它是否是一种未定义的行为,如下例所示? 我正在一个大型项目中使用类似的代码。GCC-O2和-O3输出错误值。如果我添加-fno严格的别名,问题就不存在了。此外

    • 这是一个典型的严格混叠违规示例: 但假设我们添加第二: 这段代码正确吗(不调用未定义的行为)? 标准[expr.reinterpret.cast]如下: 注意:将“指针到<code>T1</code>”类型的prvalue转换为“指针到 和<code>T2是对象类型,并且<code>T2的对齐要求不比<code>T 1 我们使用 类型的原始指针值来访问 类型。 当优化打开时,GCC和Clang都会

    • 对于评估,我希望使用DexGuard加密APK文件中的所有字符串,但不使用模糊、收缩或优化选项 这是可能的还是我被迫混淆APK来加密它 我使用以下命令行加密所有类: conf.pro如下所示: 我已经使用了工具获取所有类名,然后使用

    • 我不知道为什么下面的代码运行得很好,没有< code>gcc错误(< code >-f strict-aliasing-Wstrict-aliasing = 1 )。 如果我遵循严格的别名规则: n1570,§6.5表达式 对象的存储值只能由具有以下类型之一的左值表达式访问: -与对象的有效类型兼容的类型, — 与对象的有效类型兼容的类型的限定版本, -与对象的有效类型对应的有符号或无符号类型的类

    • 我最近通过从源代码编译在CentOS机器上安装了Python 2.7.3。Python 2.7.3安装在/opt/python2.7上,当我安装它时,我只需更改/usr/bin/Python以指向新版本。这显然是错误的,因为当我这样做的时候,它打破了百胜。我会得到以下内容。 我更改了/usr/bin/python以指向python 2.6.6,但现在2.6.6是python的默认版本。你知道怎么解