[comp.lang.c] what C needs

devine@cookie.dec.com (Bob Devine) (12/25/87)

  I don't know if my previous message about 'noalias' got out
to the list (there was a problem at the decnet/uucp gateway
machine).  To repeat the gist: I dissapproved of the standards
committee creating a new feature that does not solve any
outstanding problem with the language.  The 'noalias' idea is
just a hint for compilers to emit faster code.  To its detriment,
'noalias' further complicates code maintenance for a possible
small speed increase.

  Something I wish that the committee *had* turned there attention
to is the memory layout of members inside a structure.  Pascal
provides a packed/no-packed approach, all C guarentees is that the
members occur in memory in the same order that they were declared.
When writing code that requires control of alignment or location,
I find myself using a char array in which I place the members or
even using unions inside the structure to "force" alignment and
placement. This is much more of a problem -- for inter-exchange or
portability -- than is 'noalias'.

  One approach is a pragma to say if a structure is to be laid out
in a memory-efficient or a retrieval-efficient manner.  
For example, how does the struct { char a; short b; char c; } get
allocated on a random machine?  C's answer is: it depends on the
machine's architecture and the compiler used.  One compiler may
put the 3 members into one long-word; a different compiler might
decide to align each on short-word boundaries.

Bob

dhesi@bsu-cs.UUCP (Rahul Dhesi) (01/01/88)

In article <8712241909.AA03710@decwrl.dec.com> devine@cookie.dec.com 
(Bob Devine) writes:
>  Something I wish that the committee *had* turned there attention
>to is the memory layout of members inside a structure.  Pascal
>provides a packed/no-packed approach...

Another interesting thing about Pascal, that ANSI might want to
consider, is the idea of a level 0 (the basic language) and a level 1
(the fancy stuff).  ISO level 0 C would be essentially K&R C plus
function prototypes and a standardized library.  ISO level 1 C would
have all the fancy stuff, such as noalias, string concatenation, token
pasting, parentheses being not rearranged, etc.  Portable code could be
written in level 0, and level 0 compilers would become available much
sooner.
-- 
Rahul Dhesi         UUCP:  <backbones>!{iuvax,pur-ee,uunet}!bsu-cs!dhesi

eric@snark.UUCP (Eric S. Raymond) (01/03/88)

In article <1759@bsu-cs.UUCP>, dhesi@bsu-cs.UUCP (Rahul Dhesi) writes:
>Another interesting thing about Pascal, that ANSI might want to
>consider, is the idea of a level 0 (the basic language) and a level 1
>(the fancy stuff).

Sorry, Rahul, because I like your political postings, but I have to give this
idea the big "Woof! Woof!".  Look what happened to ISO Pascal as a result --
half the compiler vendors supported only the crippled level 0 and got to make
a virtue of their laziness, and the other half mixed (usually botched) level
1 support with their own (incompatible, naturally) extensions.

Net result: level 1 became effectively verboten for portable code *and stayed
that way*, and Pascal is moribund. Granted, there have been other reasons for
its decline, but it is all too easy to imagine a C standard with 'levels'
falling victim to the same debilitating disease.

Let's please allow this idea to die a quick and quiet death.

[still bearing scars from my years as a Pascal hacker]


-- 
      Eric S. Raymond
      UUCP:  {{seismo,ihnp4,rutgers}!cbmvax,sdcrdcf!burdvax,vu-vlsi}!snark!eric
      Post:  22 South Warren Avenue, Malvern, PA 19355    Phone: (215)-296-5718

gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/06/88)

In article <8712241909.AA03710@decwrl.dec.com> devine@cookie.dec.com (Bob Devine) writes:
>When writing code that requires control of alignment or location,
>I find myself using a char array in which I place the members or
>even using unions inside the structure to "force" alignment and
>placement. This is much more of a problem -- for inter-exchange or
>portability -- than is 'noalias'.

If you're under the impression that a simple, efficient mechanism
exists or could feasibly be made to exist for "rolling in" raw binary
data obtained from another system, you're sadly mistaken.  I've had
to deal with this many times, and it would not have helped much to
have had "packed" data.  The problems are more pervasive than that.

It would perhaps be of some use on the same system, to conform to
externally-imposed formats, but it isn't usually much harder to
perform I/O for each contiguous piece of the external data than to
try to roll a whole record at a time in or out.

gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/06/88)

In article <1759@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) writes:
>Another interesting thing about Pascal, that ANSI might want to
>consider, is the idea of a level 0 (the basic language) and a level 1
>(the fancy stuff).

X3J11 did consider defining multiple language "levels", long ago,
and decided they did not want that.  I think the argument was that
even if agreement could be reached on what went into the "minimal"
level, nobody would actually want that subset anyway.

peter@sugar.UUCP (Peter da Silva) (01/07/88)

In article <143@snark.UUCP>, eric@snark.UUCP (Eric S. Raymond) writes:
> In article <1759@bsu-cs.UUCP>, dhesi@bsu-cs.UUCP (Rahul Dhesi) writes:
> >Another interesting thing about Pascal that ANSI might want to
> >consider is the idea of a level 0 ... and a level 1 [compiler].

>                              Look what happened to ISO Pascal as a result --
> half the compiler vendors supported only the crippled level 0 and... the
> other half mixed ... level 1 ... with their own extensions.

BUT, level 0 pascal WAS crippled. Level 0 'C' is a superset of existing 'C'
compilers. Not only is it not crippled, it's better than what we have now.

ALSO, the 'C' compiler market is highly competitive. The first level 0
compilers WILL be quickly replaced by level 1 compiler, at least for the
vendors wanting to stay in business.
-- 
-- Peter da Silva  `-_-'  ...!hoptoad!academ!uhnix1!sugar!peter
-- Disclaimer: These U aren't mere opinions... these are *values*.

tim@doug.UUCP (Tim J Ihde) (01/08/88)

In article <6926@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes:
> In article <8712241909.AA03710@decwrl.dec.com> devine@cookie.dec.com (Bob Devine) writes:
> >When writing code that requires control of alignment or location,
> >I find myself using a char array in which I place the members or
> >even using unions inside the structure to "force" alignment and
> >placement.
> 
> ...
> 
> It would perhaps be of some use on the same system, to conform to
> externally-imposed formats, but it isn't usually much harder to
> perform I/O for each contiguous piece of the external data than to
> try to roll a whole record at a time in or out.

Usually this is what one ends up doing; but this raises a question
with respect to the new ANSI structure passing (pass-by-value) rules.
Suppose I have a structure like:

struct
    {
    char	one[3] ;
    int		two ;
    } alpha, beta ;

On my system there will be at least one extra byte in between the two
locations 'one' and 'two', used so 'two' will be properly aligned.
Normally I would take great pains to make sure that this extra data
does not end up effecting anything, such as being certain to process
'one' and 'two' individually and not 'alpha' as a whole.  However, this
extra data does get passed along sometimes, such as with C-ISAM where you
must do record oriented operations.

My question is: as long as I know this byte is there, then I might potentially
use it for something.  If 'alpha' is a key that a hash algorythm will be
used on, the extra byte will be part of the hash result.  This would
probably have caused so much trouble that I would have defined 'one'
to be of length 4 just to get away from this; but IF I HADN'T . . . .

What happens to this extra byte when I do
	beta = alpha ;
	    or
	foo(alpha) ;
	    ??

Is the extra byte copied along, or is it filled with new-and-improved
undefined garbage?  In other words, do the new structure operations do
memory moves or do they copy each field individually?
-- 
Tim J. Ihde					ihnp4!ctsmain!doug!tim
(201) 535-9897

Ok, we can all agree that this is my fault.

gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/08/88)

In article <496@doug.UUCP> tim@doug.UUCP (Tim J Ihde) writes:
>Is the extra byte copied along, or is it filled with new-and-improved
>undefined garbage?

I don't think struct "holes" have guaranteed behavior one way or the other.
The destination hole might get random garbage, the source hole's contents,
0 fill, or be left unchanged, depending on the implementation.

am@cam-cl.UUCP (01/15/88)

In article <6995@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
[re holes in structures, when passed by value]
>>Is the extra byte copied along, or is it filled with new-and-improved
>>undefined garbage?
>
>I don't think struct "holes" have guaranteed behavior one way or the other.
>The destination hole might get random garbage, the source hole's contents,
>0 fill, or be left unchanged, depending on the implementation.
What about a machine which initialises its stack with parity errors
(or other trapping values) to trap some uses of a value before definition
(such programs are undefined).
Clearly if I (illegally) do
    f() { struct { int a,b; } x;
          x.b = 1;
          g(x);
       }
then I would expect undefined behaviour (and risk a trap).  How about
    f2() { struct { char a; int b; } x;
          x.a = 1, x.b = 1;
          g2(x);
       }
??
The same problem occurs with union values passed by value when the value is
not of the largest component.
Are we really saying that referencing *some* uninitialised locations
is not undefined?
See section 3.5.6 [initialisation] in Oct 86 DpANS for loose words.
--
Alan Mycroft am@cl.cam.ac.uk

gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/18/88)

In article <1128@jenny.cl.cam.ac.uk> am@cl.cam.ac.uk (Alan Mycroft) writes:
-What about a machine which initialises its stack with parity errors
-...  How about
-    f2() { struct { char a; int b; } x;
-          x.a = 1, x.b = 1;
-          g2(x);
-       }

The implementation is not allowed to cause a trap when passing x to g2().
If it wants to flag holes specially so they cause a trap when touched,
then it will have to pass struct arguments member-by-member.

nobody@ism780c.UUCP (Unprivileged user) (01/19/88)

In article <7116@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>In article <1128@jenny.cl.cam.ac.uk> am@cl.cam.ac.uk (Alan Mycroft) writes:
>-What about a machine which initialises its stack with parity errors
>-...  How about
>-    f2() { struct { char a; int b; } x;
>-          x.a = 1, x.b = 1;
>-          g2(x);
>-       }
>
>The implementation is not allowed to cause a trap when passing x to g2().
>If it wants to flag holes specially so they cause a trap when touched,
>then it will have to pass struct arguments member-by-member.

Another thing that a legal implementation may do is to generate code to
assign to the pad bytes (if any) when a reference to a near by variable is
incountered.  For example the assignemt:

	      x.a = 1;

may fill the pad that exists between x.a and x.b.  For most machines this no
more costly than leaving the pad bytes undefined.

    Marv Rubinstein  -- Interactive Systems