什么是有效的类型由memset的写了一个对象? [英] What is the effective type of an object written by memset?

查看:139
本文介绍了什么是有效的类型由memset的写了一个对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

code 1:

 无符号整型* P =的malloc(sizeof的* P);
memset的(对,将0x55,sizeof的* P);unsigned int类型U = * P;

code 2:

 无效* D =的malloc(50);
*(双*)D = 1.23;
memset的(D,将0x55,50);unsigned int类型U = *(unsigned int类型*)D;

在每种情况下,不会有什么影响 memset的对有效类型的malloc分配空间中的目标;所以正在初始化 U 正确或严格别名违规?

的定义的有效类型的(C11 6.5 / 6)是:


  的 有效类型的的用于向它的存储值的访问的对象的是对象的声明的类型,如果有的话。如果值被存储到一个对象具有带类型不是字符类型,那么左值的类型成为了访问和不修改的后续访问的有效对象的类型通过左值没有声明的类型存储的值。如果值被复制到一个对象具有不使用任何类型声明的memcpy memmove与,或者被复制为数组字符类型,则有效类型的访问和对不修改该值的后续访问的修改的对象的是有效的类型从该值被复制,如果有对象的。对于所有其他的访问不具有声明类型的对象中,有效的对象的类型是简单地用于接入左值的类型。


不过,目前尚不清楚 memset的的行为是否想通过字符类型,或者其他什么东西的左值写作。 memset的的说明(7.24.6.1)是不是很有启发:


  

该memset的功能复制的c由s指向的值(转换为 unsigned char型)到每个对象的前n个字符的。



解决方案

我50CT:

首先,我打破了这种成句子,方便参考:


  1. 用于向它的存储值的访问的有效类型的一个对象是该对象的声明的类型,如果有的话。

  2. 如果一个值被存储到一个对象具有带类型不是字符类型,那么左值的类型成为了访问和该做后续访问的有效对象的类型通过左值没有声明的类型不要修改存储的值。

  3. 如果一个数值被复制到一个对象有使用的memcpy或memmove与任何声明的类型,或者被复制为字符类型,则有效类型的访问已修改对象的数组和不修改的后续访问值是有效类型从该值将被复制的对象,如果它有一个。

  4. 对于所有其他的访问不具有声明类型的对象中,有效的对象的类型是简单地用于接入左值的类型。

脚注可能有助于在这里:​​87)分配的对象都没有声明的类型

DNA:不适用

案例1:


  • memset的(...):1:DNA(没有声明的类型),2:DNA(memset的写入字符 - 语义),3:DNA(没有的memcpy的memmove也没有),4:的char [] 为memset的内部只(不永久)

  • unsigned int类型U = * P :1:DNA(没有声明的类型),2/3:DNA(没有写,但读),4:左值的类型为 unsigned int类型

结论:没有违规,但国际pretion是实现定义,实际值取决于变量和字节顺序排列在

案例2:


  • *(双*)D = 1.23; :2: D 变成双* ,这和以下的读取。

  • memset的(D,将0x55,50); :相同案例1

  • unsigned int类型U = *(unsigned int类型*)D D 还是双* :砰!

在任何方式, memset的()是不豆蔻使用 - 字符标量,除非使用 0 ,这仍然是的的实施依赖的,既不(浮点)0.0 ,还是空指针的需要是实际上是所有位零。

最后:


  • 2句不适用 memset的,因为在内部, memset的()复制成炭:.. .of C(转换为unsigned char型)到每个第n个字符的......(或使用字符语义,至少,在实际执行在这里无关紧要)

  • 3句不适用于 memset的(),要么,因为这仅适用于的memcpy / memmove与或字符类型的数组复印时。它也没有(但前者做的,所以在 -condition只是使一个明确的复制循环相当于函数)。

  • memset的()做的的修改的有效类型的对象。这不同于的memcpy memmove与。导致从句子4,其中不包括...该访问和后续访问...作为2和3状态和1表示。

希望有所帮助。的建设性的批评欢迎。

Code 1:

unsigned int *p = malloc(sizeof *p);
memset(p, 0x55, sizeof *p);

unsigned int u = *p;

Code 2:

void *d = malloc(50);
*(double *)d = 1.23;
memset(d, 0x55, 50);

unsigned int u = *(unsigned int *)d;

In each case, what effect does memset have on the effective type of the object in the malloc'd space; and so is initializing u correct or a strict aliasing violation?

The definition of effective type (C11 6.5/6) is:

The effective type of an object for an access to its stored value is the declared type of the object, if any. If a value is stored into an object having no declared type through an lvalue having a type that is not a character type, then the type of the lvalue becomes the effective type of the object for that access and for subsequent accesses that do not modify the stored value. If a value is copied into an object having no declared type using memcpy or memmove, or is copied as an array of character type, then the effective type of the modified object for that access and for subsequent accesses that do not modify the value is the effective type of the object from which the value is copied, if it has one. For all other accesses to an object having no declared type, the effective type of the object is simply the type of the lvalue used for the access.

However it is unclear whether memset behaves like writing through an lvalue of character type, or something else. The description of memset (7.24.6.1) is not very illuminating:

The memset function copies the value of c (converted to an unsigned char) into each of the first n characters of the object pointed to by s.

解决方案

My 50ct:

First, I break this into sentences for easier reference:

  1. The effective type of an object for an access to its stored value is the declared type of the object, if any.
  2. If a value is stored into an object having no declared type through an lvalue having a type that is not a character type, then the type of the lvalue becomes the effective type of the object for that access and for subsequent accesses that do not modify the stored value.
  3. If a value is copied into an object having no declared type using memcpy or memmove, or is copied as an array of character type, then the effective type of the modified object for that access and for subsequent accesses that do not modify the value is the effective type of the object from which the value is copied, if it has one.
  4. For all other accesses to an object having no declared type, the effective type of the object is simply the type of the lvalue used for the access.

The footnote might help here: "87) Allocated objects have no declared type.".

DNA: "does not apply"

Case 1:

  • memset(...): 1: DNA (no declared type), 2: DNA (memset writes to char - semantics), 3: DNA (neither memcpy nor memmove), 4: char [] for memset internally only (not permanent).
  • unsigned int u = *p: 1: DNA (no declared type), 2/3: DNA (no write, but read), 4: type of lvalue is unsigned int.

Conclusion: no violation, but the interpretion is implementation defined, as the actual value depends on alignment within the variable and endianess.

Case 2:

  • *(double *)d = 1.23;: 2: d becomes double * for this and following reads.
  • memset(d, 0x55, 50);: same as for Case 1.
  • unsigned int u = *(unsigned int *)d: d is still double *: bang!

In any way, memset() is of litte use for non-char scalars, except if using 0, which is still implementation dependent, as neither (float)0.0, nor the null pointer need to be actually "all bits zero".

Finally:

  • Sentence 2 does not apply to memset, as internally, memset() copies by char: "...of c (converted to an unsigned char) into each of the first n characters ..." (or uses char semantics, at least; the actual implementation is irrelevant here).
  • Sentence 3 does not apply to memset(), either, as that only applies to memcpy/memmove or when copying as "an array of character type". Which it also does not (but the former do, so the or-condition just makes an explicit copy-loop equivalent to the functions).
  • memset() does not change the effective type of the object. That differs from memcpy and memmove. That results from sentence 4, which does not include "... for that access and for subsequent accesses ..." as 2 and 3 state and 1 implies.

Hope that helps. Constructive criticism welcome.

这篇关于什么是有效的类型由memset的写了一个对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆