views:

101

answers:

2

I'm going through the code of Unix version 6 with the Lion's book. One of the header files (param.h, can be accessed here) defines the following structs:

/*struct to access integers*/

/*single integer */
struct { int integ; };

/*in bytes*/
struct { char lobyte; char hibyte; };

These structures don't seem to define any instance, nor are they named so they can be used later. Does anybody know what is their use?

Thanks

+5  A: 

If someone included the whole file in a union declaration, it would allow them to access the different parts.

It would be something like:


  union{
   #include <param.h>
  } myparam;

  myparam.integ = 0xDEAD;
  assert(myparam.lobyte == 0xAD)
  assert(myparam.hibyte == 0xDE)

(Depends on endianness of architecture...)

So having looked around a bit, it seems that in old versions of C, you wouldn't have needed to declare the union ; there was only one namespace for all struct/union members that just translated into a byte offset that you could use on any variable. The best mention of this I could find is here : http://docs.sun.com/source/806-3567/compat.html Describing pre-ISO Sun C:

Allows struct, union, and arithmetic types using member selection operators ('.', '->') to work on members of other struct(s) or unions.
rjw
Is it just me or is that an extremely convoluted way of doing it? I'm doubtful this is what it was meant for. I commend you for finding a way to actually make the code do something useful though.
Matti Virkkunen
I have to admit, I'm not sure. I have seen some horrific union/ struct/ include tricks in old C code. It didn't seem so weird when you were coming from assembly - structs and unions were often thought of as a description of memory layout, rather than a type declaration.
rjw
it does seem to be used as if it were a union but without specifically declaring it. So for example, if there is an integer, you see things like myint.lobyte. param.h does include a lot of other constants which mean that including it inside an union probably wouldn't work .It probably has something do with ancient C
lordsandwich
The #define s wouldn't matter - they are all just on the level of the C preprocessor, so wouldn't affect things once it got to the c compiler.
rjw
I think you are right that in old versions of C, you wouldn't have needed to declare the union ; there was only one namespace for all struct/union members that just translated into a byte offset that you could use on any variable. The best mention of this I could find is here : http://docs.sun.com/source/806-3567/compat.html Describing pre-ISO Sun C:<blockquote> Allows struct, union, and arithmetic types using member selection operators ('.', '->') to work on members of other struct(s) or unions.</blockquote>
rjw
@rjw: That's very useful info - you should update your answer with that in place of the `union` speculation.
caf
I did the edit, but I think its a bit weird to be editing answers other people have commented on. It means their comments are no longer referring to the correct thing. I guess this is one for meta...
rjw
@rjw: The way I see it is that the comments are just fluff, but the answers are for posterity.
caf
@rjw that's right! It makes perfect sense, thank you! You should have written as a full answer.
lordsandwich
er... you know I modified the answer, right?
rjw
A: 

Back in those days, the members of structures all shared the same namespace, not one namespace per structure. Consequently, each element of a structure had to have a unique name across all structures, or the same element had to appear with the same type at the same offset in every structure in which it appeared. Quite how that was used with these, I'm not sure, but I suspect you could do:

int x;

x.lobyte = 1;
x.hibyte = 2;

Or something analogous to that.

See also:

(Neither of those seems to answer this question, though.)

Jonathan Leffler