Do any compilers transfer effective type through memcpy/memmove

↘锁芯ラ 提交于 2019-12-04 05:22:11

The C standard says that the effective type is transferred. Therefore, by definition, all conforming compilers transfer the effective type.

Your code sample causes undefined behaviour by violating the strict aliasing rule, because a value of effective type long is read by an lvalue of type long long.

This was also true in C89, I'm not sure what you refer to about "new rules in C99" (other than the fact that long long was not in C89).

It is true that when C was standardized, some existing code had undefined behaviour. And it is also true that people continue to write code with undefined behaviour.

What is meant by "copied as an array of character type"?

This means copying character-by-character using a character type.

what would be the proper way of copying data in type-agnostic fashion?

It's not possible to "erase effective type", so far as I know. To correctly read a value using a long long *, you must be pointing to a location of effective type long long.

In your code, for example:

// If we have confirmed that long and long long have the same size and representation
long long x;
memcpy(&x, p, sizeof x);
return x;

Union aliasing is another option.

If you don't like all this then compile with -fno-strict-aliasing.

Experimentally, gcc 6.2 behaves in ways which would only be justifiable by regarding memmove as transferring the effective type of the source to the destination. If gcc can determine that the source and destination pointers match, it will treat the memory operand as only being readable via its earlier Effective Type, rather than as memory which was last written using a character type and may thus be accessed using any type. Such behavior would be unjustifiable without the rule that allows memcpy to transfer effective-type information.

On the other hand, gcc's behavior is sometimes not justifiable under any rule, so it's not necessarily clear whether gcc's behavior is a consequence of its authors' interpretation of the Standard, or whether it's simply broken. For example, if it can determine that the destination target of memcpy contains the same constant bit pattern as the source, it will treat the memcpy as a no-op even if the source held the type that would next be used to read the destination storage, and the destination held a different type the compiler had decided couldn't alias the next read.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!