ANSI C idea: structure literals (and short constants)

Frank Adams franka at mmintl.UUCP
Tue Mar 29 06:57:23 AEST 1988


In article <744 at viper.Lynx.MN.Org> john at viper.Lynx.MN.Org (John Stanley) writes:
>In article <2768 at mmintl.UUCP> franka at mmintl.UUCP (Frank Adams) writes:
> >[Quoting Henry Spencer, if memory serves.  Henry, just to set the record
> > straight, was commenting on someone else's proposal, not mine.]
> >>They're not, but the point is that this is a totally new meaning for a
> >>cast.  Usually, a cast is a unary operator.  Here, it's part of the
> >>description, like a declaration.  ...  Also, your (struct ..) cast will
> >>produce an lvalue, which is also a big inconsistency.
> >
> >This is the wrong the interpretation of this syntax.  If such a syntax is
> >adopted, the correct interpretation runs as follows:
>
>  While I agree that the original poster had the wrong idea, I somewhat
>resent the attitude that your interpretation is "The one and only"
>correct one.

The attitude you resent is a figment of your imagination.  I was, of course,
just expressing my opinion.  You are free to agree or disagree.  I've even
been wrong once or twice in my life (:-).

> >Casting a struct to another struct results in an element by element cast
> >of the components of the first struct to the components of the second.
> >Likewise for casting a struct to an array.
>
>What if the struct(s) have a different number of elements?

To match the K&R initialization syntax as closely as possible, when casting
to a struct with more elements, set the excess to zeros.  When casting to a
struct with fewer elements, one could either ignore the extra ones, or
report an error from the compiler.  I would lean toward the latter.

This does mean that extra braces in initializations become non-optional.
That is, one can no longer write:

int x[2][2] = {1, 2, 3, 4};

but must instead use

int x[2][2] = {{1, 2}, {3, 4}};

This is a non-trivial change.  It may be possible to adjust the definition
so that this does not happen; I'll have to think about it.

>What happens if you cast a struct containing a long into a character array?

The long gets converted to a character.  C remains an industrial-strength
language.

> >	Taking the address of a constant results in a literal copy of
> >	the constant being allocated, and the result is a constant
> >	pointer to that literal.
>
>  I can't see any usefulness to this part of your proposal.  It
>introduces the necessity for dynamic creation of data with the
>mechinism compleatly hidden from the programmer.

You misunderstand.  I want the *compiler* to allocate the literal copy, not
the *program*.  The same way it does now for statements like:

char * p = "This is a string.";

>Currently, there's no difference between:
>   char aba[10] = "abcdefghi";
>      and
>   char aba[10] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', '\0'};
>and I can't see any reason we should change this aspect of the language...

Right.  Under this proposal, there is also no difference between:
   char *abc = "abcdefghi";
      and
   char *abc = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', '\0'};

Whereas the latter is currently illegal.

> >The main problem with this proposal is the parsing problem.  When do {}'s
> >enclose a struct literal, and when a compound statement?  The parser
> >must be able to tell when it sees the first {.
>
>It's not the parsers job to know anything about compound statements or
>structs...  The compiler, on the other hand, should be able to
>differentiate from context (same way it would when compiling a variable
>definition line like the char array one given above).

Guess again.  "The part of the compiler which differentiates things from
context" is a fairly good definition of the parser.  You are perhaps
confusing it with the scanner, which divides the source code into tokens.
(This terminology is not completely standard, but very nearly so.)

Roughly, the problem is that one must look arbitrarily far ahead in the
source code to disambiguate the two constructs in some cases.  Modern
parsing techniques depend on being able to do so relatively quickly.

Compare, for example, the following statements:

   {1, 2, 3, 4, 5, 6, 7;}

vs

   {1, 2, 3, 4, 5, 6, 7};

Now, neither of these statements actually does anything, but both are legal
C statements (the first already, the second with the proposed enhancement).
The first is a compound statement, containing no declarations and a single
enclosed statement.  That statement is an expression, involving 7 constants,
and 6 "," operators.  The second is an expression statement; the expression
is anonymous structure constant, with 7 components.  Yet, we cannot tell
them apart until we get practically to the end.
-- 

Frank Adams                           ihnp4!philabs!pwa-b!mmintl!franka
Ashton-Tate          52 Oakland Ave North         E. Hartford, CT 06108



More information about the Comp.lang.c mailing list