[comp.lang.c] Compilers and programming style

martin@mwtech.UUCP (Martin Weitzel) (12/20/89)

In article <1989Dec18.113539.10935@gdt.bath.ac.uk> exspes@gdr.bath.ac.uk (P E Smee) writes:
[some lines deleted]
>I have a pathlogical dislike for the comma operator, because its most
>common use seems to be to allow overloading of too many unrelated concepts
>into one source line, in a sort of 'Gosh, amn't I clever' coding style.
>Banning it altogether is probably excessive, because I think there are
>occasions when it helps make things clearer or more efficient.  I do wish,

Agreed.

>though, that someone could put a heuristic into the compiler so that it
>would be rejected if it is being used because it is 'flash' rather than
>because it wins something in the context. :-)

Compiler writers look: His smiley tells, he doesn't really mean it!
Please don't put such stuff into your compilers - or make it optional
at least (!) - because *I* have a pathlogical dislike for compilers,
that do the following:

1. Example

	FILE *fp;
	if (fp = fopen("somefile", "r"))
		/* do somthing with fp */
	else
		/* handle errors */

	*** Compiler warning: "Do you mean equality?"

2. Example

	#if __STDC__ != 1
	#define const /*empty*/
	#endif

	*** Compiler error: "const will become a reserved word
		in future releases and may not be redefined"

Arrgh! I could continue here, but what I wanted to point out should
allready be clear: Some heuristics, a single compiler writer likes
(because it doesn't break his or her programming style) may strike
back on *many* others, who use perfectly legal constructs.

There should be other tools than the compiler, to control programming
style, from 'intelligent' beautifiers to proprietary style checkers,
but *please* leave the compiler to what K&R and ANSI allows.


-- 
Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83

exspes@gdr.bath.ac.uk (P E Smee) (12/22/89)

In article <564@mwtech.UUCP> martin@mwtech.UUCP (Martin Weitzel) writes:
>In article <1989Dec18.113539.10935@gdt.bath.ac.uk> exspes@gdr.bath.ac.uk (P E Smee) writes:
>
>>though, that someone could put a heuristic into the compiler so that it
>>would be rejected if it is being used because it is 'flash' rather than
>>because it wins something in the context. :-)
>
>Compiler writers look: His smiley tells, he doesn't really mean it!

Well spotted.  Well, really I was only *half* kidding, but Martin is right,
the compiler is not actually the place.  See below.

>There should be other tools than the compiler, to control programming
>style, from 'intelligent' beautifiers to proprietary style checkers,
>but *please* leave the compiler to what K&R and ANSI allows.

Yep.  The compiler should allow anything which is presently legal.  If it
wants to include 'do you really mean it' heuristics, they should only be
applied if you ask for them with some special control argument, and the
default should be not to use them.  (Actually, though, I'd rather see
them in something like an expanded and improved lint, or a totally new
'is-this-sensible' language checker.  How about, maybe, 'cstyle', by
analogy with 'style'?)

A compiler should *never* of its own choice put out gratuitous warnings
about valid constructs, as many places will not allow release of code
unless it compiles with NO messages at all; and because a compiler which
forces you to ignore chatty messages will someday lead you to miss an
important one.

I do think, though, that a compiler which will accept code written to
either of 2 standards (say, K&R-1 and ANSI, or FORTRAN 66 and FORTRAN
77, or whatever) should provide a set of switches so that you can ask
it to enforce compliance with whichever one you prefer.

-- 
Paul Smee, Univ of Bristol Comp Centre, Bristol BS8 1TW, Tel +44 272 303132
 Smee@bristol.ac.uk  :-)  (..!uunet!ukc!gdr.bath.ac.uk!exspes if you MUST)

amull@Morgan.COM (Andrew P. Mullhaupt) (12/24/89)

In article <1989Dec22.100135.2903@gdt.bath.ac.uk>, exspes@gdr.bath.ac.uk (P E Smee) writes:
> In article <564@mwtech.UUCP> martin@mwtech.UUCP (Martin Weitzel) writes:
> >
> 
> >There should be other tools than the compiler, to control programming
> >style, from 'intelligent' beautifiers to proprietary style checkers,
> >but *please* leave the compiler to what K&R and ANSI allows.
> 
> Yep.  The compiler should allow anything which is presently legal.  If it
> wants to include 'do you really mean it' heuristics, they should only be
> applied if you ask for them with some special control argument, and the
> default should be not to use them.  (Actually, though, I'd rather see
> them in something like an expanded and improved lint, or a totally new
> 'is-this-sensible' language checker.  How about, maybe, 'cstyle', by
> analogy with 'style'?)
> 
> I do think, though, that a compiler which will accept code written to
I think you've got a tough problem in developing a really useful utility
here. There seem to be several groups of C programmers with somewhat
incompatible ideas of good style. My special interest so far has been 
the structure of control statements, but this is one of the easier
issues. Some of the really hard ones are things like the choice of
factoring functions within and across source files, which depends on
the author's perception of the likelihood  of modifications to or
re-uses of the code as given. I don't think a C style checker can 
correctly arrive at judgements on this 'global' kind of decision by
looking at the source alone. There are other 'global' issues like
naming conventions, whether to use the preprocessor or not, etc.
which will probably be very hard to arbitrate based on the source.
(It would be possibly to include 'pragmas' which could inform the
source style checker, but I can't see much short of this working well.

	Even in the 'peephole' style issues, there will be disagreement
between programmers on what is good style. I often check the style
used in large source projects by grepping the "for" and "while" and
"do" constructs, to examine some of the gross statistics which can
sometimes indicate the programmers' collective styles in the project. 
The ratio of "for" constructs to "while" constructs seems to have
a bimodal distribution with some projects falling in the 50-50 split
(I fall in this camp) and another group where the ratio is much
higher than one (I call this the "while-averse" style). In the while
averse style, you often find "for" constructs with empty clauses,
(unless the controlled statement contains a continue), a "for"
construct with empty first clause is really a "while" construct in
disguise. Even though I prefer one of these styles to the other,
I would expect to catch flak if I built that into a style checker.

	The issue of style in C programming is compounded by the 
wide range of variation in optimizations provided by different
compilers. On the Sun 4, it turns out that 'unrolling' "for"
constructs does not pay off with Sun's 'cc', (not because the
'rolled' code is fast, but because the compiler generates pretty
stupid code for 'unrolled' loops). The gnu compiler gcc generates
much more sensible code (and returns a 10-fold performance gain
in many loops which occur in APL interpreters, which is of deep
concern to us). It seems that the correct style for 'cc' is to
ignore the unrolling possibility (which we have written macros
for) and stick to straightforward C, but for gcc, the speedup is
too much to ignore and the use of the macros, (which expand to
'non-readable' code) is justified. It seems that to correctly 
judge code, the style checker needs to see both if the macros
(and other preprocessor inputs) are good, and it also needs to
see inside the expansion (preprocessor outputs), and differentiate
on the basis of the nature of optimizations available.

Later,
Andrew Mullhaupt

mikes@rtech.UUCP (Mike Schilling) (12/24/89)

From article <1989Dec22.100135.2903@gdt.bath.ac.uk>, by exspes@gdr.bath.ac.uk (P E Smee):
> A compiler should *never* of its own choice put out gratuitous warnings
> about valid constructs, as many places will not allow release of code
> unless it compiles with NO messages at all; and because a compiler which
> forces you to ignore chatty messages will someday lead you to miss an
> important one.
How about this:

sub()
{
	extern void (*ptr)();

	*ptr;		/* Should be (*ptr)(), of course */
}

This is legal c, but almost certainly *not* what was intended.  Most compilers
I've used don't flag this as an error, or even a warning.  In fact, there was
a posting in comp.lang.c yesterday by someone who did this, and couldn't figure
out why his function wasn't being called.  Isn't a chatty message in order?

exspes@gdr.bath.ac.uk (P E Smee) (12/31/89)

In article <4367@rtech.rtech.com> mikes@rtech.UUCP (Mike Schilling) writes:
>From article <1989Dec22.100135.2903@gdt.bath.ac.uk>, by exspes@gdr.bath.ac.uk (P E Smee):
>> A compiler should *never* of its own choice put out gratuitous warnings
>> about valid constructs, as many places will not allow release of code
>> unless it compiles with NO messages at all; and because a compiler which
>> forces you to ignore chatty messages will someday lead you to miss an
>> important one.
>How about this:
>
>sub()
>{
>	extern void (*ptr)();
>
>	*ptr;		/* Should be (*ptr)(), of course */
>}
>
>This is legal c, but almost certainly *not* what was intended.  Most compilers
>I've used don't flag this as an error, or even a warning.  In fact, there was
>a posting in comp.lang.c yesterday by someone who did this, and couldn't figure
>out why his function wasn't being called.  Isn't a chatty message in order?

Well, we're getting into theology, but *I* would say that the COMPILER should
silently accept this, UNLESS you've used some '-chatty_messages' command
line switch.  Lint, or my hypothetical 'cstyle' should warn you.

However, I wouldn't object terribly to a message in this case as the statement,
while valid as written, clearly has no effects and no side effects.  I'm
willing to bend my principles a bit (or at least not offended by having
them bent) to allow a compiler to complain about obviously unused blocks
of code, unreachable statements, and statements with no effects or side
effects.

-- 
Paul Smee, Univ of Bristol Comp Centre, Bristol BS8 1TW, Tel +44 272 303132
 Smee@bristol.ac.uk  :-)  (..!uunet!ukc!gdr.bath.ac.uk!exspes if you MUST)

bret@codonics.COM (Bret Orsburn) (01/04/90)

In article <1989Dec31.153241.16479@gdt.bath.ac.uk> exspes@gdr.bath.ac.uk (P E Smee) writes:
>>
>>	*ptr;		/* Should be (*ptr)(), of course */
>
>while valid as written, clearly has no effects and no side effects.

Let me get something clear: are_you/is_anybody claiming that *all* isolated
pointer dereferences are inherently worthless (hence, fair game for whining
compilers), or would you reserve this judgement just for the special case of
an isolated pointer-to-function?

If you are making the former, stronger claim, I could cite a lot of counter-
examples from the realm of Systems Programming (read: Pounding on Hardware).

-- 
-------------------
bret@codonics.com
uunet!codonics!bret                 C Is Not Baroque
Bret Orsburn                          Don't Fix It

tneff@bfmny0.UU.NET (Tom Neff) (01/04/90)

If you have a specialized systems/hardware-type situation where merely
referring to a variable has useful side effects, then you can cast it
to (void) or some such, to make this obvious.  Otherwise, it's probably
a coding error and lint should catch it.

The issue of how much of lint's work the c compiler ought to do is a
separate one.
-- 
Annex Canada now!  We need the room,    \)      Tom Neff
    and who's going to stop us.         (\      tneff@bfmny0.UU.NET

exspes@gdr.bath.ac.uk (P E Smee) (01/05/90)

In article <649@codonics.COM> bret@codonics.com (Bret Orsburn) writes:
>In article <1989Dec31.153241.16479@gdt.bath.ac.uk> exspes@gdr.bath.ac.uk (P E Smee) writes:
>>>
>>>	*ptr;		/* Should be (*ptr)(), of course */
>>
>>while valid as written, clearly has no effects and no side effects.
>
>Let me get something clear: are_you/is_anybody claiming that *all* isolated
>pointer dereferences are inherently worthless (hence, fair game for whining
>compilers), or would you reserve this judgement just for the special case of
>an isolated pointer-to-function?

Did you miss the beginning of this chain, then?  I *was* claiming that
isolated pointer deferences to *functions* had no effects and no
side-effects.  I was *also* saying, though, that as the construct is
valid C, the compiler has *no business* whining (I used 'chatting', but
the idea's the same) about it, unless the user has used some special
command-line -switch which means 'I want to get whined at'.  I was
claiming even more strongly that a compiler should not, (at least as
its default behaviour) put out messages complaining about constructs
which are linguistically valid.

>If you are making the former, stronger claim, I could cite a lot of counter-
>examples from the realm of Systems Programming (read: Pounding on Hardware).

Probably.  I have since (in continued email discussion with various
people) realised that I can think of at least one context from my past
experience where I would expect 'isolated pointer dereference to a
function' to cause (machine-dependent) meaningful side-effects.  I was
already aware of the possible (mchine/system dependent) uses for
apparently isolated dereferences of other pointers, so would agree that
the stronger claim is incorrect.  I am now of the opinion that even the
weaker claim is not always correct.

And, I'd reiterate, even if something is patently, obviously, provably
always useless, if it is linguistically valid the default behavior of
the compiler should be to accept it.  Silently.

I would add two more threads to this, though.  The compiler has to do a
fair amount of flow analysis (particularly if it tries any
optimisation) and so it would be handy, IMHO, if compilers included a
(non-default) -switch which said 'I would like you to whine about
anything you don't understand'.  And I think it would be useful to have
a 'noddy' compiler for less computer literate users (I see a lot of
them) which DID put out excessive warnings, alongside the 'professional
production' compiler which didn't.  In order that the two have a
consistent view of the language, I would actually suggest that they
ought to be the same program, accessed by different names, in the
manner of vi/view/ed on Unices.

-- 
Paul Smee, Univ of Bristol Comp Centre, Bristol BS8 1TW, Tel +44 272 303132
 Smee@bristol.ac.uk  :-)  (..!uunet!ukc!gdr.bath.ac.uk!exspes if you MUST)

exspes@gdr.bath.ac.uk (P E Smee) (01/05/90)

In article <15065@bfmny0.UU.NET> tneff@bfmny0.UU.NET (Tom Neff) writes:
>If you have a specialized systems/hardware-type situation where merely
>referring to a variable has useful side effects, then you can cast it
>to (void) or some such, to make this obvious.  Otherwise, it's probably
>a coding error and lint should catch it.

True, always best to leave flags for whoever has to maintain your code
next.  (If you're unlucky, it might even be you. :-)  A useful use of
(void) casts.  I also like to use '/* nobreak; */' statements when I
want a switch case to fall through.

>The issue of how much of lint's work the c compiler ought to do is a
>separate one.

My humble opinion is none at all, unless the compiler has a -switch which
allows you to ask for it, and you've used the switch.

-- 
Paul Smee, Univ of Bristol Comp Centre, Bristol BS8 1TW, Tel +44 272 303132
 Smee@bristol.ac.uk  :-)  (..!uunet!ukc!gdr.bath.ac.uk!exspes if you MUST)

mikes@rtech.UUCP (Mike Schilling) (01/06/90)

From article <649@codonics.COM>, by bret@codonics.COM (Bret Orsburn):
> In article <1989Dec31.153241.16479@gdt.bath.ac.uk> exspes@gdr.bath.ac.uk (P E Smee) writes:
>>>
>>>	*ptr;		/* Should be (*ptr)(), of course */
>>
>>while valid as written, clearly has no effects and no side effects.
> 
> Let me get something clear: are_you/is_anybody claiming that *all* isolated
> pointer dereferences are inherently worthless ...

I'm claiming exactly that.  To claim the contary, one has to assert the 
following:

1. Dereferencing a pointer is an absolute command to read the location pointed
   to, unless *optimization* is allowed.
2. A high-level language is a tool for generating a precise sequence of
   machine instructions.

I don't believe either of those.  I've done my share of hardware hacking, but
in assembly language, as God intended.
----------------------------------------------------------------------------
Any resemblance between the opinions expressed above and those of any living
person is a coincidence.
mikes@rtech.com = Mike Schilling, Ingres Corporation, Alameda, CA

bret@codonics.COM (Bret Orsburn) (01/06/90)

There's a smiley in here somewhere, I just know it! (Musta got blasted by
my Telebit :-)

But, just in case:

In article <4406@rtech.rtech.com> you write:
>From article <649@codonics.COM>, by bret@codonics.COM (Bret Orsburn):
>> 
>> Let me get something clear: are_you/is_anybody claiming that *all* isolated
>> pointer dereferences are inherently worthless ...
>
>I'm claiming exactly that.  To claim the contary, one has to assert the 
>following:
>
>1. Dereferencing a pointer is an absolute command to read the location pointed
>   to, unless *optimization* is allowed.

Where C is concerned, that is an admirably succinct and comprehensive
statement of my view. Thank you.

>2. A high-level language is a tool for generating a precise sequence of
>   machine instructions.

I would not assert that.

I would also not assert that C is a High Level Language, although there is
considerable room for disagreement here. I was taught that C is an
"Intermediate Level Systems Programming Language", but I would hasten to
add that I think both of those terms are too fuzzy to be of much use.

BUT, fortunately, the distinction is moot, because I also would NOT assert:

    An intermediate-level language is a tool for generating a precise sequence
    of machine instructions.

That assertion is too strong. Assertion number 1, above, is sufficient.

>I don't believe either of those.  I've done my share of hardware hacking, but
>in assembly language, as God intended.

Missing smiley goes here, I trust?
-- 
-------------------
bret@codonics.com
uunet!codonics!bret                 C Is Not Baroque
Bret Orsburn                          Don't Fix It

bright@Data-IO.COM (Walter Bright) (01/09/90)

int *p;
*p;		/* has no side effects and should be optimized away,	*/
		/* a warning is justified here as it is probably a	*/
		/* mistake						*/

(void) *p;	/* has no side effects and should be optimized away,	*/
		/* no warning should be generated			*/

volatile int *p;
*p;		/* has side effects and must not be optimized away	*/

scott@bbxsda.UUCP (Scott Amspoker) (01/09/90)

In article <2283@dataio.Data-IO.COM> bright@dataio.Data-IO.COM (Walter Bright) writes:
>volatile int *p;
>*p;		/* has side effects and must not be optimized away	*/

Just curious - what kind of code should be generated for the above
C fragment?


-- 
Scott Amspoker
Basis International, Albuquerque, NM
(505) 345-5232
unmvax.cs.unm.edu!bbx!bbxsda!scott

tim@nucleus.amd.com (Tim Olson) (01/09/90)

In article <534@bbxsda.UUCP> scott@bbxsda.UUCP (Scott Amspoker) writes:
| In article <2283@dataio.Data-IO.COM> bright@dataio.Data-IO.COM (Walter Bright) writes:
| >volatile int *p;
| >*p;		/* has side effects and must not be optimized away	*/
| 
| Just curious - what kind of code should be generated for the above
| C fragment?

The integer pointed to by p should be accessed from memory and thrown
away (this may be useful in talking to certain peripheral devices).
For example:

w "t.c",L3/C3:  q: Expression has no side-effects.

;f(int *q, volatile int *p)
;{
;       *q;
;       *p;
        load    0,0,gr96,lr3
;}      jmpi    lr0
        nop


The expression "*q;" generated no code and produced a compiler warning
that it had no side-effects.  However, the expression "*p;", since p
was declared as a pointer to a volatile object, generates an access to
that object which is then subsequently thrown away.


	-- Tim Olson
	Advanced Micro Devices
	(tim@amd.com)

jeter@ficc.uu.net (john jeter) (01/10/90)

In article <15065@bfmny0.UU.NET>, tneff@bfmny0.UU.NET (Tom Neff) writes:
> If you have a specialized systems/hardware-type situation where merely
> referring to a variable has useful side effects, then you can cast it
> to (void) or some such, to make this obvious. 
                          ^^^^^^^^^^^^^^^^^^^^
A little used alternate approach is the usage of the commentary operator
in close proximity to the variable reference. ;-)

hascall@cs.iastate.edu (John Hascall) (01/10/90)

In article <534> scott@bbxsda.UUCP (Scott Amspoker) writes:
}In article <2283> bright@dataio.Data-IO.COM (Walter Bright) writes:

}>volatile int *p;
}>*p;		/* has side effects and must not be optimized away	*/
 
}Just curious - what kind of code should be generated for the above
}C fragment?

   (using VAX-11 as an example)

	  MOVL   @P,temp         ; move int pointed to by P into a throwaway
      or
          TSTL   @P              ; compare int pointed to by P to zero

   If you've never written a device driver, you may not understand why
   you would want to do this.  Some compilers will even `help' you out
   by `optimizing':

	  temp = *p;
      or
          if (*p);

John Hascall  /  ISU Comp Ctr

exspes@gdr.bath.ac.uk (P E Smee) (01/10/90)

In article <534@bbxsda.UUCP> scott@bbxsda.UUCP (Scott Amspoker) writes:
>In article <2283@dataio.Data-IO.COM> bright@dataio.Data-IO.COM (Walter Bright) writes:
>>volatile int *p;
>>*p;		/* has side effects and must not be optimized away	*/
>
>Just curious - what kind of code should be generated for the above
>C fragment?

Precisely the same code as if you had written:

    pp = *p;    /* pp of a suitably sensible data type */

except that it doesn't have to include the final store into a memory location.

More complicatedly, anything the compiler writer likes which has the
same side effects as would have occurred if the value of *p had then
been used.  (If on a particular machine, the answer is provably
guaranteed always to be 'none at all', then the statement *could* be
optimized out by compilers specific to that machine.)

-- 
Paul Smee, Univ of Bristol Comp Centre, Bristol BS8 1TW, Tel +44 272 303132
 Smee@bristol.ac.uk  :-)  (..!uunet!ukc!gdr.bath.ac.uk!exspes if you MUST)

scott@bbxsda.UUCP (Scott Amspoker) (01/11/90)

In article <279@dino.cs.iastate.edu> hascall@cs.iastate.edu (John Hascall) writes:
>}Just curious - what kind of code should be generated for the above
>}C fragment?
>
>   (using VAX-11 as an example)
>
>	  MOVL   @P,temp         ; move int pointed to by P into a throwaway
>      or
>          TSTL   @P              ; compare int pointed to by P to zero
>
>   If you've never written a device driver, you may not understand why
>   you would want to do this.

I've written plenty of device drivers and I still wouldn't do it.  I 
suppose that since device drivers are extremely implementation dependant
it probably wouldn't hurt to assume that the C semantics for
 
    *p;

would cause a TSTL instruction - especially if by experimentation you
discover that to be true on your particular compiler.  I just don't
recall reading that anywhere.  If I wanted to merely access a memory
location I would do something like

   dummy = *p;

But even then, some compilers might throw that away if dummy is dead
(which it probably is).


-- 
Scott Amspoker
Basis International, Albuquerque, NM
(505) 345-5232
unmvax.cs.unm.edu!bbx!bbxsda!scott

scott@bbxsda.UUCP (Scott Amspoker) (01/11/90)

In article <28716@amdcad.AMD.COM> tim@amd.com (Tim Olson) writes:
>In article <534@bbxsda.UUCP> scott@bbxsda.UUCP (Scott Amspoker) writes:
>| In article <2283@dataio.Data-IO.COM> bright@dataio.Data-IO.COM (Walter Bright) writes:
>| >volatile int *p;
>| >*p;		/* has side effects and must not be optimized away	*/
>| 
>| Just curious - what kind of code should be generated for the above
>| C fragment?
>
>The integer pointed to by p should be accessed from memory and thrown
>away (this may be useful in talking to certain peripheral devices).

By "should" I assume you mean that this is in the ANSI specification?

-- 
Scott Amspoker
Basis International, Albuquerque, NM
(505) 345-5232
unmvax.cs.unm.edu!bbx!bbxsda!scott

boyne@hplvli.HP.COM (Art Boyne) (01/11/90)

scott@bbxsda.UUCP (Scott Amspoker) writes:
>bright@dataio.Data-IO.COM (Walter Bright) writes:
>>volatile int *p;
>>*p;		/* has side effects and must not be optimized away	*/

>Just curious - what kind of code should be generated for the above
>C fragment?

Simple: a read of the address pointed to by |p|, of whatever # of bits
an int is defined as on your particular machine.

The C code I write is mostly firmware built into instruments, and I
have repeatedly used this construct to force a read of a hardware
register, eg., to clear/disable an interrupt or other condition.

Art Boyne, boyne@hplvla.hp.com

bright@Data-IO.COM (Walter Bright) (01/11/90)

In article <534@bbxsda.UUCP> scott@bbxsda.UUCP (Scott Amspoker) writes:
<In article <2283@dataio.Data-IO.COM> bright@dataio.Data-IO.COM (Walter Bright) writes:
<<volatile int *p;
<<*p;		/* has side effects and must not be optimized away	*/
<Just curious - what kind of code should be generated for the above C fragment?

Should be something like:
	MOV BX,p
	MOV AX,[BX]

scott@bbxsda.UUCP (Scott Amspoker) (01/11/90)

In article <2288@dataio.Data-IO.COM> bright@dataio.Data-IO.COM (Walter Bright) writes:
>In article <534@bbxsda.UUCP> scott@bbxsda.UUCP (Scott Amspoker) writes:
><In article <2283@dataio.Data-IO.COM> bright@dataio.Data-IO.COM (Walter Bright) writes:
><<volatile int *p;
><<*p;		/* has side effects and must not be optimized away	*/
><Just curious - what kind of code should be generated for the above C fragment?
>
>Should be something like:
>	MOV BX,p
>	MOV AX,[BX]

I don't mean to be a pain in the butt but I want to make sure I
understand what's going on.  Several posters have responded with
similar code examples.  *Is this documented in the ANSI spec?*
It's a nice "feature" and all, but....

(The reason I ask is that there are usually two kinds of postings
in this newsgroup - those that discuss C as it really is (which
I care about) and those that discuss C as someone would like
it to be (which are a waste of my time).  I sometimes have
trouble telling the two apart.  I currently don't have the
ANSI draft at my disposal but I do have compilers that claim
to be ANSI compatible with reasonably good documentation.
None of this discusses any semantics for "*p;".)

-- 
Scott Amspoker
Basis International, Albuquerque, NM
(505) 345-5232
unmvax.cs.unm.edu!bbx!bbxsda!scott

bret@codonics.COM (Bret Orsburn) (01/12/90)

In article <544@bbxsda.UUCP> scott@bbxsda.UUCP (Scott Amspoker) writes:
>
>I currently don't have the
>ANSI draft at my disposal but I do have compilers that claim
>to be ANSI compatible with reasonably good documentation.
>None of this discusses any semantics for "*p;".

I don't know about ANSI, but in K&R I, "*p" is a trivial case of an expression
(page 214) and "*p;" is a statement (page 218). To treat them otherwise is to
make them a Special Case, which I hold to be a Prima Facie Evil, only to be
considered if it is the lesser of N evils, where N >= 2.

As far as C is concerned, the semantics of the operation are the same as they
would be in a non-trivial context. The memory location is read, and precisely
nothing is done with the contents. This is a handy thing for tickling hardware.

On the machine level, the semantics are whatever the hardware designer decided
to make them. Reading a memory location, after all, is mostly just a matter of
setting up the address bus and issuing a read pulse. For example: I worked on
a design where a read from a certain location caused a latch to be reset.
The latch was used  in an interprocessor communication scheme. This is not a
unique instance. I can think of three designs like this right off the top of
my head.

As someone else pointed out, this same objective can be accomplished by
assigning the result to a temporary variable. However, that is (1) not more
syntactically correct, (2) is only marginally safer where optimization is
concerned, (3) wastes machine cycles. (OK, that is not a popular subject.
Just remember this the next time you're waiting for your computer to finish
its RAM test.)

Note that nobody on either side of this thread has suggested taking this nit
out of "lint"; lint (traditionally) has a very different mission than does "cc".

To paraphrase somebody: If we did not have a C that behaved this way, we would
surely have to invent one.
-- 
-------------------
bret@codonics.com
uunet!codonics!bret                 C Is Not Baroque
Bret Orsburn                          Don't Fix It

walter@hpclwjm.HP.COM (Walter Murray) (01/13/90)

> volatile int *p;
> *p;		/* has side effects and must not be optimized away	*/

> Just curious - what kind of code should be generated for the above
> C fragment?

The Standard says, "What constitutes an access to an object that has
volatile-qualified type is implementation-defined."  Section 3.5.3

In other words, when you buy an ANSI-conforming C, it will be
accompanied by a document that will define the semantics of the
fragment above.

Walter Murray
----------