Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

C/C++ Programmers

Name: Anonymous 2011-11-24 12:59

Why must they feel the need to redefine all the primitives with different names?

Name: Anonymous 2011-11-24 17:25

>>8

In C, the programmer is "invited" to worry about some aspects of the program which most other programming languages do not directly address. Whether it is good or bad, it's a matter of opinion, but in C, things like size and alignment are meaningful for the programmer.

A structure in C is, in the vast majority of cases, larger than the relevant word size. This is true when the structure contains more than one field, specially when padding is involved. Since there is no overloading in C as there is in C++, types don't mean too much by themselves except for what they hold, contain or represent; it is not very useful to attempt to use structure types as tags to select overloads or to perform other kinds of static code generation. Therefore, it is rather meaningless to declare a struct only to contain a single element (you'd use the single element directly instead), or to otherwise contain word-sized data which would fit better in a single word (and without the unavoidable padding penalties involved within structures).

Thus, a structure is often a rather "big" data chunk which should be treated differently from smaller (scalar) data types. For example, while it is wise to pass around copies of scalar types to routines, it is unwise to do the same with large structures; it is better to pass a (possibly const) pointer to it in order to achieve the same effect. It is also bad to directly return structures; a pointer to an output buffer is usually better. And while it is ok to stack-allocate int arrays in the stack, you'd rather avoid it with structures, since they can be much larger than an int, and may trash your stack area. With a structure, you expect it to be larger than you typical int variable, and you will refrain from doing a lot of things which you would do with scalar types.

So, typedef struct is bad in a number of aspects. First, they disguise a structure as being an ordinary scalar type: it is hard to tell whether it is really a redefined scalar type (which is also bad), hard to tell whether it is addressable, whether they can be dereferenced (if pointers to structures), and so on. People may even attempt to do arithmetic with it, as if the type were really a scalar type (think about someone implementing a binary tree with your structure type as data, and using plain subtraction as a comparation criteria -- it won't work on aggregate types).

Second, they pollute the ordinary namespace unnecessarily. For structures, unions and enumerations, there is the tag namespace -- an entire separate identifier namespace for that purpose. Some code even do things like:


typedef struct my_struct {
    // ...
} my_struct;


which is doubly bad, since they pollute both namespaces with the same identifier. This is a minor cause of problems but it is nonetheless good to avoid messing up too much with identifiers, specially because C lacks proper namespacing mechanisms.

Third, typically people who apply typedef to structure types will do the same with unions. By simply looking at the type you can't differentiate a structure from a union, and the access to them is exactly the same (and they can even contain exactly the same members). While strong syntax is no excuse for lack of proper testing, in this particular case the syntax does help to better understand the code and avoid stupid mistakes.

Last, typedef in C is, in common practice, bad not only on structures, but in everything else. A typedef does not declare a new type: it's just an alias the compiler will happily ignore. Thus, it helps to do what should not be done in C: hiding information from the programmer. You can't properly printf() or scanf() typedef'fed variables, since you can't say if it is an int or long. You can't bitwise operate in it because it might be a float. You can't assign to it safely: it might be const. typedef is roughly meant to substitute #define, thus it limits itself to almost only what #define can achieve. It is meant to create opaque types due to standard-wide constraints and other implementation-specific issues, and even then, these types are very well documented.

Roughly the same apply for putting typedef together with unions (without the same sizing problems, but with the same syntactical unawareness problems), enumerations (namespace pollution) and types in general, when it is visibly not needed.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List