Looking for C's equivalent of Pascal's "with"

Discussion in 'C Programming' started by Ruud Baltissen, Oct 2, 2013.

  1. Hello,


    The Pascal equivalent of struct is record. It is possible to nest records inside other records, just like with structs. Assume record Drive0 is nested inside record Device and has the elements InUse and PCfile:

    Device = record
    ...
    ...
    Drive0 = record
    InUse : boolean;
    PCfile : string;
    ...
    end;
    ...
    end;

    If I want to access PCfile of Drive0 I could do it like this:
    Device.Drive0.PCfile := "D:\disk.ima";
    In C it would look about the same. But in Pascal there another way:

    with Device do
    begin
    ...
    ...
    with Drive0 do
    begin
    InUse := True;
    PCfile := "D:\disk.ima";
    end;
    end;

    This comes in handy when handling a lot of elements in one go, for example: when initializing a drive.

    I'm looking for a C equivalent of this "with" construction. All programming examples I saw so far always showed the complete structure. Is there an equivalent or not?

    Thank you for your time and info!


    Kind regards, Ruud Baltissen
    www.Baltissen.org
     
    Ruud Baltissen, Oct 2, 2013
    #1
    1. Advertisements

  2. Ruud Baltissen

    Eric Sosman Guest

    There's nothing that lets you omit the entire "provenance"
    of a struct or sub-struct. However, you can use a pointer
    variable to collapse or condense some outer nesting levels.
    For example, here's a struct containing sub-struct elements:

    struct inner {
    int this;
    int that;
    };

    struct outer {
    struct inner one;
    struct inner two;
    struct inner three;
    } instance;

    One way to access the members is to write `instance.one.this'
    and `instance.three.that' and so on. Another is to aim a
    pointer variable at the particular inner struct you care about
    at the moment, and use that instead:

    struct inner *p = &instance.two;
    p->this = 42;
    p->that = 17;

    This technique can collapse additional levels if desired:

    struct atomic {
    double trouble;
    short snort;
    };

    struct inner {
    int this;
    int that;
    struct atomic redThing;
    struct atomic blueThing;
    };

    struct outer {
    struct inner one;
    struct inner two;
    struct inner three;
    } instance;

    struct atomic *q = &instance.three.redThing;
    q->trouble = 3.17;
    q->snort = 0;

    .... instead of `instance.three.redThing.trouble = ...' and so on.
     
    Eric Sosman, Oct 2, 2013
    #2
    1. Advertisements

  3. Ruud Baltissen

    BartC Guest

    You can use something like this

    struct S drive0 = {.InUse =True, .PCfile = "D:\\disk.ima"};

    (although I've never used it myself). I don't know how it works if drive0 is
    nested; you either have to initialise the whole Device struct, or create
    drive0 as above then just assign it: Device.Drive0 = drive0;

    (I think that can done in one go in with certain C systems.)
     
    BartC, Oct 2, 2013
    #3
  4. Ruud Baltissen

    Nobody Guest

    No.

    However, given a structure, you can obtain a pointer to any field within
    that structure, then access fields via that pointer. So when dealing with
    nested structures, it's not uncommon to take a pointer to some
    sub-structure and assign it to a variable. You can't make fields appear as
    variables, but you can collapse the top-level variable name and any number
    of intervening levels into a single variable.
     
    Nobody, Oct 2, 2013
    #4
  5. The example given had "..." after the two members explicitly shown.
    That suggested to me that assignment of the whole thing would probably
    be more trouble that it's worth.
     
    Ben Bacarisse, Oct 2, 2013
    #5
  6. Ruud Baltissen

    BartC Guest

    Possibly, but at least it would replace the repetition of 'Device.Drive0'.

    I suppose the OP can also try this:

    #define DD Device.Drive0

    DD.InUse = True;
    DD.PCfile = "D:\\dis.ima";

    #undef DD

    which at least involved less typing.
     
    BartC, Oct 2, 2013
    #6
  7. Ruud Baltissen

    Jorgen Grahn Guest

    .
    A personal note:

    I really prefer when people do this. Avoiding temporary pointers can
    rather quickly lead to decreased readability, when the same (or
    deceptively similar) long expression is repeated over and over again.

    fie.foo[bar].baz.bat.barney = something;
    fie.foo[bar].baz.bat.fred = something;
    ...

    In C++ you can use references for this, but a constant pointer in C is
    almost as good.

    /Jorgen
     
    Jorgen Grahn, Oct 3, 2013
    #7
  8. Ruud Baltissen

    Ian Collins Guest

    A good analogy for posting via that awful google Usenet interface!
     
    Ian Collins, Oct 3, 2013
    #8
  9. I wonder how it compares to partial qualification in PL/I.
    PL/I allows (as far as I know, inherited from COBOL) structure
    members to be references with partial qualification if it isn't
    ambiguous.

    If you have A.B.C, and there are no other C's in the program,
    then C is enough. If there are, either A.C or B.C might work.

    PL/I also allows moving the subscripts in a structure reference.
    A(I).B(J).C(K) can be written A.B.C(I,J,K) or vice versa.
    (The compiler knows where they go in any case.) This one I
    am more sure came from COBOL. As I understand it, COBOL only
    allows for 1D arrays, so structure nesting is used to generate
    higher dimensionality.

    -- glen
     
    glen herrmannsfeldt, Oct 3, 2013
    #9
  10. Ruud Baltissen

    Fred K Guest

    What a terrible idea!
    Suppose I have a struct AA containing members a through z, each of which is itself a different kind of struct of, and those structs contained members aa through zz, etc., all of these being defined in different files.

    Then my code says
    int i = www;

    It would be a nightmare trying to find the struct that this instance of www belongs to, especially if some of those modules contained local variables named www.


    <snip>
     
    Fred K, Oct 4, 2013
    #10
  11. No, stone knives and bearskins.
     
    Keith Thompson, Oct 5, 2013
    #11
  12. Ruud Baltissen

    Lew Pitcher Guest

    XKCD #378
    "*Real* programmers use butterflies. They open their hands and let the
    delicate wings flap once. The disturbance ripples outwards, changing the
    flow of the eddy currents in the upper atmosphere. These cause momentary
    pockets of higher-pressure air to form, which act as lenses deflecting
    incoming cosmic rays, focusing them to strike the drive platter and flip
    the desired bit."

    (http://xkcd.com/378/)
     
    Lew Pitcher, Oct 5, 2013
    #12
  13. Ruud Baltissen

    Sc0rpi0 Guest

    One more ugly aproach - preprocesor :p

    #define as begin and #undef as end;
    where for example defined D0(a) or D1(a) would become Device.Drive0.a
    or D1(a) would be Device.Drive1.a or something like that :).

    D0(InUse), D0(PCFile) etc.
     
    Sc0rpi0, Oct 11, 2013
    #13
  14. The use of macros has already been suggested (sorry, I forget who by)
    but the suggestion did not use function-like macros. I think your use
    of them just makes things more complex (D0.InUse is surely simpler than
    D0(InUse)).

    If I try to imagine a situation where the function-like macro can be
    used to construct the symbol (i.e. D(0) becomes the token 'Drive0') then
    I start to think I need to re-write this code!
     
    Ben Bacarisse, Oct 11, 2013
    #14
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.