For example, the results returned by the old gethostbyname Posix function. Its return type is a struct hostent * but sometimes it returns a pointer to a structure which has the same elements, but with a few more tacked onto the end. You can then cast your result to a pointer to the real type if you want to access the extra stuff. The net result is kind of like returning an object of a subclass of the declared return type in an OO language.

Is there a name for this kind of "subclassing" in C? Is it regarded as a good practice?

有帮助吗?

解决方案 3

I believe this is called type punning.

In computer science, type punning is a common term for any programming technique that subverts or circumvents the type system of a programming language in order to achieve an effect that would be difficult or impossible to achieve within the bounds of the formal language.

In C and C++, constructs such as type conversion, union, and reinterpret_cast are provided in order to permit many kinds of type punning, although some kinds are not actually supported by the standard language.

As for if it is good practice or not, it makes certain assumptions about the alignment of the data in the structure, but that's rarely an issue. If the alignment of the two structures are different, then severe errors could occur.

If true inheritance is used, as in C++, there is no danger of incompatible alignments, and the efficiency is exactly the same.

其他提示

If you create a union of the two types, then the members at the beginning form a "common initial sequence". The standard specifically allows you to access members of that common initial sequence via any of those members (C99, § 6.5.2.3/5):

One special guarantee is made in order to simplify the use of unions: if a union contains several structures that share a common initial sequence (see below), and if the union object currently contains one of these structures, it is permitted to inspect the common initial part of any of them anywhere that a declaration of the complete type of the union is visible. Two structures share a common initial sequence if corresponding members have compatible types (and, for bit-fields, the same widths) for a sequence of one or more initial members.

The same idea was called 'variant' records in Pascal. The better way to implement this is to define a struct for the common initial sequence, and have the variations declare a prefix element of that struct. But this is often not done, and likely because of the extra name in the reference to the initial struct members. (Mis)Using the preprocessor and including the prefix struct, or other tricks simply to avoid naming the common values.

Alternately, the variant parts can be named sub-structures, and then a union of these variant parts can be declared at the end of the structure. Remember that C is a typed language, and a systems language, and so developers often try to write brief code that (mostly) obeys the type rules.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top