[comp.lang.c] Addressing struct without ->

NIBMSCM@NDSUVM1.BITNET (01/10/91)

  In working with some of the more common 'C' packages, I've found
one limiting factor that seems to come back and haunt me.  In working
with some other languages, such as Pascal, I had the capability to use
the 'using' keyword, giving the address of a structure and then address
the elements of that structure without the necessity of using the
ptr->element notation (could simply use element).
  Could anyone out there tell me how I can implement this in 'C' or
which language products have added such a function (currently using
the bundled 'C' on SunOS).  Thanks in advance...
 ___________
|           |   Regards,
| N.D.----> *:      Steve Malme    -->NIBMSCM@NDSUVM1.NODAK.EDU<--
|____________|      FBS Data Systems

henry@zoo.toronto.edu (Henry Spencer) (01/12/91)

In article <91010.084408NIBMSCM@NDSUVM1.BITNET> NIBMSCM@NDSUVM1.BITNET writes:
>with some other languages, such as Pascal, I had the capability to use
>the 'using' keyword, giving the address of a structure and then address
>the elements of that structure without the necessity of using the
>ptr->element notation (could simply use element).
>  Could anyone out there tell me how I can implement this in 'C' ...

Can't be done (in any convenient way) in standard C.
-- 
If the Space Shuttle was the answer,   | Henry Spencer at U of Toronto Zoology
what was the question?                 |  henry@zoo.toronto.edu   utzoo!henry

gwyn@smoke.brl.mil (Doug Gwyn) (01/12/91)

In article <91010.084408NIBMSCM@NDSUVM1.BITNET> NIBMSCM@NDSUVM1.BITNET writes:
>... the 'using' keyword ...
>  Could anyone out there tell me how I can implement this in 'C' or
>which language products have added such a function ...

Since any such extension would be highly nonstandard, you really ought
to avoid using it.  It would provide no new functionality anyway, but
merely cater to your Pascal-based expectations.  C is not Pascal; it is
better.  The whole "using" approach is insufficiently general, since in
C different structure types can have the same member names, and often
do in practical source code.  Thus some form of disambiguation is needed
anyway, and this is already conveniently provided by use of the member
selection operators . and ->.  My suggestion is to learn to exploit this
rather than fight it.

dave@cs.arizona.edu (Dave P. Schaumann) (01/12/91)

In article <14822@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
>C is not Pascal; it is better.

Aaaaaaaag!!! Language Wars Alert!!! Flame sheilds on full power!!!
I would amend that statement a bit:
C is not Pascal; it is better [at some things.  Pascal is not C, it is
better at some things.]

Pascal excels at safety checks within the code, and cleanness of syntax.
C excells at having powerful tools.  Use what you need.

Dave Schaumann      | We've all got a mission in life, though we get into ruts;
dave@cs.arizona.edu | some are the cogs on the wheels, others just plain nuts.
						-Daffy Duck.

adrian@mti.mti.com (Adrian McCarthy) (01/16/91)

In article <14822@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
>... C is not Pascal; it is better. ...

Let's not start that flame war.  The application to be implemented usually
determines which language is best.

>  The whole "using" [Pascal with] approach is insufficiently general, since
> in C different structure types can have the same member names, and often
>do in practical source code.

You can have identically named fields in Pascal records too (some
non-standard compilers don't allow it).  Some older C compilers have
problems with it, too.  Aren't the fields in a struct tm are all prefixed
with tm_ to reduce the chances of a name-space conflict?

What bothers me about x.y and x->y is that I shouldn't *in many cases* have
to worry about whether x is an instance of a struct or a pointer to one.  If
I have a function that works with a struct, and I change my mind about how
to pass that struct into the function (e.g., by value instead of by
reference), it's irritating to have to mindlessly change all the occurences
of x->y to x.y and all of the calls of that function to remove the &'s.  The
mindless stuff should be done by the machine.  In this regard, C constantly
makes you worry about the low-level details when it would be more productive
to think in abstract terms.

Aid.  (adrian@gonzo.mti.com)

bright@nazgul.UUCP (Walter Bright) (01/17/91)

In article <91010.084408NIBMSCM@NDSUVM1.BITNET> NIBMSCM@NDSUVM1.BITNET writes:
/  In working with some of the more common 'C' packages, I've found
/one limiting factor that seems to come back and haunt me.  In working
/with some other languages, such as Pascal, I had the capability to use
/the 'using' keyword, giving the address of a structure and then address
/the elements of that structure without the necessity of using the
/ptr->element notation (could simply use element).
/  Could anyone out there tell me how I can implement this in 'C' or
/which language products have added such a function (currently using
/the bundled 'C' on SunOS).  Thanks in advance...

C++ currently has a similar feature, when if you are in a member function of
class X then you can access members of class X without specifying X->.

karl@ima.isc.com (Karl Heuer) (01/17/91)

In article <1290@mti.mti.com> adrian@mti.UUCP (Adrian McCarthy) writes:
>What bothers me about x.y and x->y is that I shouldn't *in many cases* have
>to worry about whether x is an instance of a struct or a pointer to one.

I see no significant difference between this and the related worry about
whether `i' is an int or a pointer to one.  If it really bothers you, use
C++ and references; or if that's too much trouble, emulate the effect with
	#define x (*px)
(I often use this when dealing with what is logically call-by-reference.)

Karl W. Z. Heuer (karl@ima.isc.com or uunet!ima!karl), The Walking Lint

wolfram@cip-s02.informatik.rwth-aachen.de (Wolfram Roesler) (02/01/91)

NIBMSCM@NDSUVM1.BITNET writes:


>  In working with some of the more common 'C' packages, I've found
>one limiting factor that seems to come back and haunt me.  In working
>with some other languages, such as Pascal, I had the capability to use
>the 'using' keyword, giving the address of a structure and then address
>the elements of that structure without the necessity of using the
>ptr->element notation (could simply use element).

You can't get the same thing in C without getting ABSOLUTELY incompatible.
You can however use the preprocessor trick to avoid long chains of -> and .
in the following way:

#define X ptr->fooptr->foo.bar.bar.baz.foobar->foobaz.x

and now write 

	X->something

instead of (well you know what).

I'm not sure if the following will work:

struct
{
  int foo;
  int bar;
} xyz;
#define foo xyz.foo
#define bar xyz.bar

zougas@me.utoronto.ca ("Athanasios(Tom) Zougas") (02/02/91)

wolfram@cip-s02.informatik.rwth-aachen.de (Wolfram Roesler) writes:

>NIBMSCM@NDSUVM1.BITNET writes:


>>		...Pascal, I had the capability to use
>>the 'using' keyword, giving the address of a structure and then address
>>the elements of that structure without the necessity of using the
>>ptr->element notation (could simply use element).
>#define X ptr->fooptr->foo.bar.bar.baz.foobar->foobaz.x
>and now write 
>	X->something
>instead of (well you know what).

Personally, I hate these types of "magic" defines. Why not just use:

	X = ptr->fooptr->foo.bar.bar.baz.foobar->foobaz.x
and the access the elements within using:

	X.element
where X is of the proper type. This also saves on all those indirections.

Tom.

-- 
I can be reached at...
  zougas@me.utoronto.ca || zougas@me.toronto.edu || ...!utai!me!zougas

dfoster@jarthur.Claremont.EDU (Derek R. Foster) (02/02/91)

In article <wolfram.665407476@cip-s02> wolfram@cip-s02.informatik.rwth-aachen.de (Wolfram Roesler) writes:
>NIBMSCM@NDSUVM1.BITNET writes:
>You can however use the preprocessor trick to avoid long chains of -> and .
>in the following way:
>
>#define X ptr->fooptr->foo.bar.bar.baz.foobar->foobaz.x
>
>and now write 
>
>	X->something
>
>instead of (well you know what).

A way that is almost always better is to assign a local, temporary
pointer to the end of that long chain, and then use tempptr->something.
Using this technique, you don't have to dereference multiple pointers
every time you access it. You also don't have the defined macro hanging
around later when you don't want it. (although #undef could be used for
this purpose also.) 

For instance,
in (probably mangled) Pascal:
-----
record ghi
  x,y:integer;
end;
record def
  g:ghi;
end; 
record abc
  d:def;
end;
var jkl : array [0..9] of abc;

BEGIN
  for i:=0 to 9 do
    with jkl[i].d.g do
    begin
      x := 1;
      y := 2;
    end;
END.
-------
in C:
-------
struct ghi {int x,y;};
struct def {ghi g;};
struct abc {def g;};
abc jkl[10];
void main(void)
{
  for (i=0; i<10; i++)
  {
    ghi * temp = & jkl[i].d.g;
    temp->x = 1;
    temp->y = 2;
  }
}

>I'm not sure if the following will work:
>
>struct
>{
>  int foo;
>  int bar;
>} xyz;
>#define foo xyz.foo
>#define bar xyz.bar

Probably not. You've created circular definitions of foo and bar with the
preprocessor. ("foo" expands to "xyz.foo" which expands to "xyz.xyz.foo"
ad infinitum.)

Derek Riippa Foster

avery@netcom.UUCP (Avery Colter) (02/04/91)

Henry Spencer writes:
>In article <91010.084408NIBMSCM@NDSUVM1.BITNET> NIBMSCM@NDSUVM1.BITNET writes:
>>with some other languages, such as Pascal, I had the capability to use
>>the 'using' keyword, giving the address of a structure and then address
>>the elements of that structure without the necessity of using the
>>ptr->element notation (could simply use element).
>>  Could anyone out there tell me how I can implement this in 'C' ...

>Can't be done (in any convenient way) in standard C.

How about....

#define element ptr->element

for each element involved?

Then, in the program itself, use ptr as a dummy, assigning it to
point to whichever structure is appropos.

-- 
Avery Ray Colter    {apple|claris}!netcom!avery  {decwrl|mips|sgi}!btr!elfcat
(415) 839-4567   "I feel love has got to come on and I want it:
                  Something big and lovely!"         - The B-52s, "Channel Z"

enag@ifi.uio.no (Erik Naggum) (02/04/91)

In article <10615@jarthur.Claremont.EDU>, Derek R. Foster writes:
   In article <wolfram.665407476@cip-s02>, Wolfram Roesler writes:
   >I'm not sure if the following will work:
   >
   >struct
   >{
   >  int foo;
   >  int bar;
   >} xyz;
   >#define foo xyz.foo
   >#define bar xyz.bar

   Probably not. You've created circular definitions of foo and bar with the
   preprocessor. ("foo" expands to "xyz.foo" which expands to "xyz.xyz.foo"
   ad infinitum.)

Only in some compilers.  ANSI C, most notably, disables expansion of
the macro name being defined in the body of the definition, as well as
in the expansion of macroes used in the definition.  Very handy.

--
When will "All the world's a VAX" be replaced by "All the world's ANSI C"?
--
[Erik Naggum]	Snail: Naggum Software / BOX 1570 VIKA / 0118 OSLO / NORWAY
		Mail: <erik@naggum.uu.no>, <enag@ifi.uio.no>
My opinions.	Wail: +47-2-836-863	Another int'l standards dude.

henry@zoo.toronto.edu (Henry Spencer) (02/05/91)

In article <22711@netcom.UUCP> avery@netcom.UUCP (Avery Colter) writes:
>>Can't be done (in any convenient way) in standard C.
>
>How about....
>#define element ptr->element
>for each element involved?

Works okay the first time, but the second time you have to #undef them
all first.  Or if you leave the macros alone and change ptr, either you
have to declare ptr in every function or you have to make it global,
which tends to reduce efficiency (notably because it interferes with
putting it into a register).  It's clumsy at best.  Also, to be portable
to old compilers you have to use different names to avoid macro recursion.
-- 
"Maybe we should tell the truth?"      | Henry Spencer at U of Toronto Zoology
"Surely we aren't that desperate yet." |  henry@zoo.toronto.edu   utzoo!henry