Request for Comments: Aggregate Assignment in C ...

Jens M. Dill jmd at dlogics.COM
Wed Dec 19 01:53:39 AEST 1990


In article <1990Dec14.130916.18447 at ctk1.UUCP>, 
    heidi at ctk1.UUCP (Heidi de Wet) writes:
> >In article <77546 at iuvax.cs.indiana.edu>, 
    mayer at iuvax.cs.indiana.edu (Mayer Goldberg) writes:
> >> [Proposed alternative to 'with' construct]
> >> We submit that a better way of doing this would be to allow ...
> >> Something like:    my_vec = {4,, 7};
> 
> As a staunch fan of Pascal, writing C for a living :-), this seems a
> very uninteresting problem.  Pascal's 'with' doesn't solve this, anyway.
> It _does_ reduce the text associated with multiple references to the
> same record structure in one expression.  Try this for size:
> 
>    (*Buff)->Msg_Bytes [(*Buff)->Start_Index + (*Buff)->Byte_Count] = B;

If you are willing to step outside of comp.lang.C for a moment, note that
C++ reference types handle this very nicely:

     {  BuffStructType  & BF = **Buff ;  /* Yes, you did have a double 
                                            ... indirection in your code */

        BF.Msg_Bytes [BF.Start_Index + BF.Byte_Count] = B ;
     }

In short: the Pascal WITH statement allows you to completely elide a complex
qualifying expression on the front of a structure reference, at the cost of
only being able to do so for one structure of a given type at any one time.
C++ references allow you to replace a complex qualifying expression with what
looks like a simple reference to a field of a named structure.  You can't get
rid of that last qualifier, but you can make it short and you do get the 
freedom to do it to more than one structure of the same type.  By the way,
C purists can do almost the same thing with pointers:

     {  BuffStructure  * BP = *Buff ;
        BP->Msg_Bytes [BP->Start_Index + BP->Byte_Count] ;
     }

Don't let the cost of the "extra" variable fool you.  It's saving you time
by precomputing most of the common addressing information.  A smart compiler
will manage to keep the new variable in a register for its entire scope, if,
like this, it's VERY local and frequently used.  If you don't have a smart
compiler, you can declare it a register variable.
 
> Now try copying one 'Buff' to another...  Any suggestions about this?
> 
> If you want to make assignments of multiple elements in a structure
> easier, how about the construct 'A = B', where A and B are identical,
> complex structs or arrays?  ...

"A = B" works fine for structures, provided A and B are the same type of
structure.  It didn't work in the earliest versions of C, (and is not in
K&R 1), but unless you have a very old C compiler it should work for you.
Arrays are a whole different kettle of fish, as any regular reader of this
newsgroup will tell you.  You can get what you want by embedding the array
inside a structure and assigning the structure, however.

But the original poster didn't have two identical structures, but rather 
wanted to be able to initialize a structure dynamically with a constant
value for each of the fields.  C allows you to do this statically (at
compile time, into a global or static variable), but does not have an
equivalent run-time initialization for automatic structures.  Neither does
Pascal.  C++ allows you to fake it by writing a "constructor function" to
do the initialization on the fly, but that brings in a whole bunch of new
syntax and semantics that are not at all related to the static initialization
("= { ... }") idea.  The best solution is to define a static "constant"
structure that can be initialized using the "= { ... }" notation, and then
initialize your automatic variable by a simple assignment from the static
"constant":

     void  foo (args ...)
     {
         static struct MyStruct  Initializer = { ... } ;
         struct MyStruct         LocalStructVar = Initializer ;
         ...
     }

You may have to split the second declaration into a declaration and an
assignment statement if your compiler is overly rigid about not allowing 
any initialization of automatic variables.
  


*=====* TIME CANNOT BE WASTED *=====*       -- Jens M. Dill
 \ But it can be used for purposes /           jmd at dlogics.com
  \ other than what was intended. /
   *=============================*



More information about the Comp.lang.c mailing list