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

R

Ruud Baltissen

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
 
E

Eric Sosman

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?

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.
 
B

BartC

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.

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.)
 
N

Nobody

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?

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.
 
B

Ben Bacarisse

BartC said:
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;

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.
 
B

BartC

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.

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.
 
J

Jorgen Grahn

.
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.

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
 
I

Ian Collins

The Pascal "WITH" statement is one of those things that seemed a good
idea at the time, but produces highly unreadable code.

A good analogy for posting via that awful google Usenet interface!
 
G

glen herrmannsfeldt

The Pascal "WITH" statement is one of those things that seemed
a good idea at the time, but produces highly unreadable code.
The problem is that any identifier within the "WITH" statement
could now have a different meaning. So if you use a local
variable or global variable within the WITH statement, and
then rename or add or remove a member of the struct, your
code might continue to compile with totally changed meaning.

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
 
F

Fred K

(e-mail address removed) wrote:












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.

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>
 
K

Keith Thompson

ralph said:
On Fri, 4 Oct 2013 11:48:08 -0700 (PDT), Fred K
Mouse over.
Open up menu.
Select Definition/Declaration if not the default.

What are you using? Clay tablets?

-ralph
<g>

No, stone knives and bearskins.
 
L

Lew Pitcher

No, stone knives and bearskins.

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/)
 
S

Sc0rpi0

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;

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.
 
B

Ben Bacarisse

Sc0rpi0 said:
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.

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!
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top