Can an object have more than one effective type?

痴心易碎 提交于 2019-12-03 15:50:32

The error is thinking that x and x.xi are the same object.

The union is an object and it contains member objects1. They are distinct objects, each with it's own type.


1. (Quoted from: ISO/IEC 9899:20x1 6.2.5 Types 20)
A union type describes an overlapping nonempty set of member objects, each of which has an optionally specified name and possibly distinct type.

Outside of the rules which forbid the use of pointers to access things of other types, the term "object" refers to a contiguous allocation of storage. Each individual variable of automatic or static duration is an independent object (since an implementation could arbitrarily scatter them throughout memory) but any region of memory created by malloc would be a single object--effectively of type "char[]", no matter how many different ways the contents therein were indexed and accessed.

The C89 rules regarding pointer type access could be made workable if, in addition to the special rule for character-pointer types, there were a corresponding rule for suitably-aligned objects of character-array types, or for objects with no declared type that were effectively "char[]". Interpreting the rules in such a fashion would limit their application to objects that had declared types. This would have allowed most of the optimizations that would have been practical in 1989, but as compilers got more sophisticated it became more desirable to be able to apply similar optimizations to allocated storage; since the rules weren't set up for that, there was little clarity as to what was or was not permissible.

By 1999, there was a substantial overlap between the kinds of pointer-based accesses some programs needed to do, and the kinds of pointer-based accesses that compilers were assuming programs wouldn't do, so any single C99 standard would have either required that some C99 implementations be made less efficient than they had been, or else allow C99 compilers to behave arbitrarily with a large corpus of code that relies upon techniques that some compilers didn't support.

The authors of C99, rather than resolving the situation by defining directives to specify different aliasing modes, attempted to "clarify" it by adding language that either requires applying a different definition of "object" from the one used elsewhere, or else requires that each allocated region hold either one array of a single type or a single structure which may contain a flexible array member. The latter restriction might be usable in a language being designed from scratch, but would effectively invalidate a huge amount of C code. Fortunately or unfortunately, however, the authors of the Standard were to get away with such sloppy drafting since compiler writers were, at least until recently, more interested in doing what was necessary to make a compiler useful than in doing the minimum necessary to comply with the poorly-written Standard.

If one wants to write code that will work with a quality compiler, ensure that any aliasing is done in ways that a compiler would have to be obtuse to ignore (e.g. if a function receives a parameter of type T*, casts it to U*, and then accesses the object as a U*, a compiler that's not being obtuse should have no trouble recognizing that the function might really be accessing a T*). If one wants to write code that will work with the most obtuse compiler imaginable... that's impossible, since the Standard doesn't require that an implementation be incapable of processing anything other than a possibly-contrived and useless program. If one wants to write code that will work on gcc, the author's willingness to support constructs will be far more relevant than what the Standard has to say about them.

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