osd7@homxa.UUCP (Orlando Sotomayor-Diaz) (01/29/85)
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@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