mod.std.c Digest V2 #10

Orlando Sotomayor-Diaz osd7 at homxa.UUCP
Tue Jan 29 09:59:57 AEST 1985


mod.std.c Digest            Mon, 28 Jan 85       Volume 2 : Issue  10 

Today's Topics:
              const foo()
	      Decot's reply to Martin (union initialization)
              Martin's clarification (union initialization)
----------------------------------------------------------------------

Date: Mon, 14 Jan 85 03:25:05 est
From: "John Levine, P.O.Box 349, Cambridge MA 02238-0349 (617-494-1400)" <ihnp4!cbosgd!ima.UUCP!johnl>
Subject: const foo()
To: cbosgd!ihnp4!houxm!homxa!osd7

PL/I has an attribute of procedures called
REDUCIBLE which means that the procedure is a true function whose value depends
only on its arguments, and that multiple calls with the same arguments can
legitimately be compiled as one call with several uses of the result.  This can
make a lot of difference, particularly in numerical code.  Fortran 77 has a
list of built in "intrinsic" functions such as sqrt() which are reducible.

I believe that there is currently no interpretation placed on "const foo()".
If so, I suggest that it mean that the procedure is a true function.  The
header file math.h would be changed so that, for example, the square root
function is:

	const double sqrt(const double);

Given that the C standard has a certain amount of stuff for the benefit of
the numerical analysis crowd, and C looks like the only game in town for those
who want to move up from Fortran, this would be a plausible thing to add.  Note
that, like const declarations in general, this declaration merely gives a hint
to the compiler about optimizations it may perform.

John Levine, ima!johnl

------------------------------

Date: Fri, 11 Jan 85 10:24:08 est
From: cbosgd!watmath!kpmartin (Kevin Martin)
Subject: Union initializers (blush)
To: cbosgd!std-c

I received my article which you returned for further details today; Yesterday,
having forgotten the original article, I sent a new article replying to
gang!hokey's proposal (the name-the-type method).

However, it looks like 'rn' has screwed things up for me (blush).
The article I sent dated the 10th refers to Dave Decot's article (from V2#5).
It should refer to cbosgd!gang!hokey (from V2#4).
Since Dave Decot in fact appears to agree with me, I withdraw both my former
articles regarding union initializers, but would like to suggest the following
change to Dave's proposal (which would solve the problems pointed out in V2#7):
Sorry for the confusion.

1) Don't bother with the '.' before the element name (or the []'s for
   array elements). They aren't needed, and they increase the parser
   complexity.
e.g.
use:

	union foo x[] = {
		int_val = 5,
		char_val = 'x',
		float_val = 2.5
	};

rather than:

	union foo x[] = {
		.int_val = 5,
		.char_val = 'x',
		.float_val = 2.5
	};

2) If no element is named for an initializer, the first element of a union
   is initialized; otherwise, the element after the previous initializer
   is initialized.
e.g.

	int array[10] = {
		0, 1, 5 = 5, 6, 7, 8, 9
	};
	/* initializes elements 0, 1, and 5-9 with their own subscripts */

                       Kevin Martin, UofW Software Development Group

------------------------------

Date: Sun, 13 Jan 85 17:23:16 pst
From: cbosgd!ucbvax!hpda!hpdsa!decot (Dave Decot)
Subject: reply to Kevin Martin
To: hpda!ucbvax!cbosgd!std-c

Excerpted from issue #8:
] Today's Topics:
] 	On Decot's union initialization scheme; another method (1)
] ---------------------------------------------------------------------
] Date: Thu, 10 Jan 85 15:45:50 est
] From: cbosgd!watmath!kpmartin (Kevin Martin)
] Subject: Union initialization; a better method
]
] In the following, 'you' refers to Dave Decot (hpdsa!decot). He writes:
] >Here goes a proposal you might have heard before.  Please let me know if
] >there are any flaws in it.  So far, nobody has been able to shoot it down.
] >
] >If the data used to initialize the union is appropriately cast, and that
] >data type is a valid member of the union, then there is no ambiguity nor
] >problem; the union will hold the value by definition, and the data will
] >be appropriately cast.
] No one can shoot it down, because it is probably sufficient to solve the
] problem. That doesn't make it a good solution.
] 
] The problem with this method is that it lacks the ability to make
] the code self-documenting. Reading the code sample you give, all I can tell
] is that (for cell[1]), you are initializing one of the (char *)'s in the
] union to a pointer to "abc". It doesn't tell me *directly* which element
] you are initializing.
...

I, Dave Decot, did *not* write any of the quoted material.  It was submitted
by gang!hokey.  My union initialization scheme was one where the member to be
initialized is named, which is self-documenting in the way requested and has
several other advantages which I will not repeat.

I am disappointed that this misquoting was permitted by the moderator,
but I understand how it might have been missed.

[ See Martin's new article below this one. People, I trust that when
you quote someone, you're quoting the right individual. -Mod- ]

What I don't understand is how Kevin Martin could use my name and not have
already read my contribution, since if he did so, he would notice that my
scheme was essentially the same as the one he presents in the above posting,
except for some syntactic sugar, an extension of the concept so that it works
for structs, a shorthand for the special case of union initialization,
a suggestion to extend the concept for sparsely initializing arrays,
and some rules.  To recap:

Syntax difference:
   Use ".member = val", not "member = val" to help the compiler
   and human reader determine that this is an explicit member selection.

Shorthand for unions (and one-member structs?):
   The braces used to "get into" a union to initialize its value may
   be omitted:
      
       union { int x; double y; } z = { .y = 23.08 };
    
   is equivalent to

       union { int x; double y; } z.y = 23.08;

Array suggestion:
   Use "[<const-expr>] = val" to initialize particular array members.

Clarification of rules: 
   Explicit initialization of selected members (or array elements) must be
   employed in each logical initializer list, or not at all.  This doesn't
   imply that a complicated initializer that uses names for some lists
   can't also use the traditional implicit positional method elsewhere.
   For example,

	struct foo {
	    struct bar {
		int x, y;
		double z;
	    } inner;
	    int a[20];
	};

	struct foo foovar[7] = {
	    [2] = {                .a = { 1, 2, 3 }   },
	    [6] = { { 6, 7, 3.6 },      { [19] = 5 }  }
	};

    is permitted.  Note that foovar[6].a[19] could be initialized
    by name while foovar[2].a[0] through foovar[2].a[2] were done
    positionally.  What this rule *does* forbid is mixing the two
    methods in a list, as was described in gang!hokey's commentary
    on my method (at least concerning arrays):

    >  It would, in my opinion, be gross if the explicit array "offset"
    >  had to be specified only on the lhs.
    >
    > struct bar x =
    > {
    >     {
    > 		[initialization for x[0] omitted for brevity--Dave]
    >     },
    >
    >     [3]{
    > 		.foo1 =
    >           {
    > 			.mint = 3;	/* does this need to be cast? */
    > 		}
    >          .i = 1
    >     }
    > };

I am not sure whether this means that gang!hokey thinks it would
be gross to allow the [3] in the presence of the implicit [0]
initialization, or whether he thinks my forbidding the mixture
is gross.  If it is the latter, it may make sense to allow mixtures
in the context of arrays, since there is a precedent for this style
in the declaration of enums.  However, if one struct or union member
is mentioned in an initializer list, it seems bad style and error
prone not to mention the rest explicitly as well.

In any case, my scheme would require an '=' after the '[3]', and
a comma before '.i = 1'.  The initialization for .mint would not
have to be cast (casts in initializations have never been permitted
except in the proposed "cast" strategy for initialization of unions
favored by Kevin Martin and others), since the type is known from
the identifier.

>    Personally, I prefer positional binding over keyword binding for union
>    initialization because I don't want to have to type in all the keywords
>    for each entry of a large table.

Positional binding is preferable wherever it is clear, of course.  It would
be ridiculous to propose elimination of it.  But it helps sometimes
to have the option of making the binding explicit.  In situations where
large tables are to be initialized, the irregularities handled by
explicitness probably do not arise much, and positional binding should be
used.  I am proposing giving the programmer a choice.

The "first member" rule should be used to determine which union member
is to be initialized in situations where no member is named by the programmer.
Since many implementations already do this, any scheme for union
initialization should include a provision for this as a default.

I am sorry that my proposal may not have been clear in these areas.

Dave ("name the member, don't cast the initializer") Decot 
decvax!ucbvax!hpda!decot

------------------------------

End of mod.std.c Digest - Mon, 28 Jan 85 18:46:15 EST
******************************
USENET -> posting only through cbosgd!std-c.
ARPA -> replies to cbosgd!std-c at BERKELEY.ARPA (NOT to INFO-C)
In all cases, you may also reply to the author(s) above.
-- 
Orlando Sotomayor-Diaz	/AT&T Bell Laboratories, Red Hill Road
			/Middletown, New Jersey, 07748 (HR 1B 316)
Tel: 201-949-9230	/UUCP: {ihnp4, houxm}!homxa!osd7  



More information about the Mod.std.c mailing list