[comp.lang.c] Optimization, volatile

jas@llama.rtech.UUCP (Jim Shankland) (04/24/88)

In article <13074@brl-adm.ARPA> dsill@NSWC-OAS.arpa (Dave Sill) writes:
>Terry Lambert writes:
>>Basically, if it works without -O, it should work with -O, regardless of what
>>the compiler writer's optimization does to achieve its goal.  If this makes
>>writing compilers harder, so what?
>
>This bears repeating.  There should be no circumstances under which
>the semantics of the language are changed by a flag to the compiler.

However, you didn't repeat it.  Your assertion is reasonable, Lambert's
is not.  The world is full of (strictly speaking) incorrect C programs
that work just fine because of some accident of hardware, the compiler
used, etc.  A good optimizer can "break" programs (actually, cause existing
bugs to become manifest) just as porting a C program from a VAX to a
Sun can.

Perhaps that sounds like nitpicking; I don't think it is.  To get back
to "volatile":  it provides a portable way to declare storage objects
that may change without notice, and thus is useful in writing portable
(not necessarily portable *everywhere*, but plenty portable for may uses)
programs that access device registers, use shared memory, signal handlers,
etc. (we've been over the whole list).

The alternatives that have been mentioned include:

	(1) "Just don't do all that silly optimization".  Then, as Dennis
	Ritchie points out, it's even possible to write system software in
	C without "volatile".  Somebody else (don't remember who)
	said something to the effect that optimization won't improve
	performance by more than 20-30% anyway, so why bother?  I
	am amused to think what my employer's customers might say if
	we told them that we could have easily made our software 20-30%
	faster, but couldn't be bothered for such an inconsequential gain.

	(2) "If you need `volatile', don't use C."  I agree, it's
	certainly more comfortable in the lifeboat once you've pushed
	some of your fellow passengers into the shark-infested waters.
	I'm just not crazy about being the one pushed out, especially
	since we "systems software" types were in this boat first.
	Tell you what:  let's push out the N.A. types instead.  They
	don't seem all that unhappy with FORTRAN, anyway.

	(3) "Let implementers of optimizing compilers come up with their
	own pragmas that can turn off certain optimizations where they
	will be destructive."  In other words, let each implementer
	add "volatile" in her own way.  However, the semantics of
	"volatile" are well-defined and broadly useful.  Making its
	use non-portable is gratuitous.  As an aside, the arguments
	over "volatile int mutex; ... ++mutex;" are a red herring.
	"volatile" clearly does not guarantee atomicity, nor is it
	intended to.

What's that?  You need the soapbox I'm standing on to do the laundry?  Oh.

Bye.


Jim Shankland
  ..!ihnp4!cpsc6a!\
               sun!rtech!jas
 ..!ucbvax!mtxinu!/

	And I will show you something different from either
	Your shadow at morning striding behind you
	Or your shadow at evening rising to meet you;
	I will show you fear in a handful of dust.

			-- T. S. Eliot

terry@wsccs.UUCP (Every system needs one) (04/28/88)

In article <2003@rtech.UUCP>, jas@llama.rtech.UUCP (Jim Shankland) writes:
> In article <13074@brl-adm.ARPA> dsill@NSWC-OAS.arpa (Dave Sill) writes:
> >I (Terry) write:
> >>Basically, if it works without -O, it should work with -O, regardless of what
> >>the compiler writer's optimization does to achieve its goal.  If this makes
> >>writing compilers harder, so what?
> >
> >This bears repeating.  There should be no circumstances under which
> >the semantics of the language are changed by a flag to the compiler.
> 
> However, you didn't repeat it.  Your assertion is reasonable, Lambert's
> is not.  The world is full of (strictly speaking) incorrect C programs
> that work just fine because of some accident of hardware, the compiler
> used, etc.

Well, before you rip my head off for a fragment (strictly speaking out of
context), consider it a basic assumption that you are compiling good code.
Further assume that the standard is K&R, not ANSI.  Keeping badly written
programs running on a single architecture was not the object of my statement;
I have clarified this in another posting this very evening.  I don't expect
non K&R-conforming programs to work.

> A good optimizer can "break" programs (actually, cause existing bugs to
> become manifest)

It shouldn't be necessary to change all the code in the world to be ANSI
conformant (instead of K&R conformant) to keep some stupid optimizer from
breaking it.

> just as porting a C program from a VAX to a Sun can.

This is the method one should use to determine if code is "bad"... but I
suggest you do not use a SUN 400* (matches all SUN 400 series) as your Sun,
as some of the assumptions it makes are _NOT_ K&R.

> Perhaps that sounds like nitpicking; I don't think it is.  To get back
> to "volatile":  it provides a portable way to declare storage objects
> that may change without notice, and thus is useful in writing portable
> (not necessarily portable *everywhere*, but plenty portable for may uses)
> programs that access device registers, use shared memory, signal handlers,
> etc. (we've been over the whole list).

yes, it's a nice toy on rare ocassion, but that's why #pragma was invented.

> 	I am amused to think what my employer's customers might say if
> 	we told them that we could have easily made our software 20-30%
> 	faster, but couldn't be bothered for such an inconsequential gain.

	A: Don't tell them and keep your job.

> 	(3) "Let implementers of optimizing compilers come up with their
> 	own pragmas that can turn off certain optimizations where they
> 	will be destructive."  In other words, let each implementer
> 	add "volatile" in her own way.  However, the semantics of
> 	"volatile" are well-defined and broadly useful.  Making its
> 	use non-portable is gratuitous.

This is silly.  If ANSI thinks they can redefine C, why should #pragma be
an effort in imagination?  Couldn't they say 'hey... use this'?

>	As an aside, the arguments over "volatile int mutex; ... ++mutex;"
>	are a red herring.  "volatile" clearly does not guarantee atomicity,
>	nor is it intended to.

No, but it might be an incentive to have it as a language feature instead of a
#dogma... Nope, doesn't swing me.


| Terry Lambert           UUCP: ...{ decvax, ihnp4 } ...utah-cs!century!terry |
| @ Century Software        OR: ...utah-cs!uplherc!sp7040!obie!wsccs!terry    |
| SLC, Utah                                                                   |
|                   These opinions are not my companies, but if you find them |
|                   useful, send a $20.00 donation to Brisbane Australia...   |
| 'Admit it! you're harrasing me because of the quote in my signature!'       |

limes@sun.uucp (Greg Limes) (04/30/88)

In article <503@wsccs.UUCP> terry@wsccs.UUCP (Every system needs one) writes:
>This is the method one should use to determine if code is "bad"... but I
>suggest you do not use a SUN 400* (matches all SUN 400 series) as your Sun,
>as some of the assumptions it makes are _NOT_ K&R.

Gee. I have used Sun equipment for the last three years, followed their
product line with avid interest for the last two, and worked there for
the last six months ... and have never heard of the Sun 400. Since
the hundreds digit tends to go up with power, and the top of the line
that I am aware of (engineer, not salesman) is the Sun-4/280, the
400 series must really be something.

End sarcasm.

Yes, the Sun-4 systems have somewhat tighter restrictions than most
previous archetectures. I would have been much happier if the hardware
supported fixup of misaligned accesses, much like the 68020 supports
arbitrarily aligned accesses. On the other hand, I do not remember K&R
saying anything about arbitrary alignment of large storage cells. A
quick look through the book, in fact, shows not only a lack of this
assumption but also careful coding in the storage allocator (section
8.7, starting page 173 in my book) to assure that allocated blocks are
properly aligned; it is assumed that, since the function returns a
pointer to a character, the compiler will convert from (char *) to
whatever type (foo *) the user wants.

Porting from a Vax to a Sun-3 uncovers lots of problems, mostly dealing
with things like NULL pointer indirection; converting to a Sun-4
uncovers even more, mostly dealing with alignment problems -- where an
assumption is made about the lack of holes in structures, or specific
layout of data memory. Maybe even some assumption is made of layout of
function parameters in memory (on Sun4, they may not even BE there).

I try to code according to what appears to be the intent of K&R; after
all, that is how I learned the language: read K&R, write something,
compile it on an 11/50, make it work, think, read K&R, ...

>> Perhaps that sounds like nitpicking; I don't think it is.  To get back
>> to "volatile":  it provides a portable way to declare storage objects
>> that may change without notice, and thus is useful in writing portable
>> (not necessarily portable *everywhere*, but plenty portable for may uses)
>> programs that access device registers, use shared memory, signal handlers,
>> etc. (we've been over the whole list).
>
>yes, it's a nice toy on rare ocassion, but that's why #pragma was invented.

Have you ever written a device driver that had a top (mainline) half and
a bottom (interrupt) half? Probably not. For you, "volatile" is a toy.
For systems programming, and anybody who uses signal(), "volatile" is a
requirement. Making it a part of the language forces the syntax to be
the same across all systems that purport to support it; all others should
give errors.

>> 	we told them that we could have easily made our software 20-30%
>> 	faster, but couldn't be bothered for such an inconsequential gain.
>
>	A: Don't tell them and keep your job.

Your customers are smarter than they look. Remember, if only one of a
hundred picks up on this, and you have a thousand, someone will bring it
up in a user's group meeting. Or, worse yet, some competitor will be 10%
faster, causing a loss of that three billion dollar federal contract
that was *so* important. If I can get a gain of 1%, I go for it.

>> 	(3) "Let implementers of optimizing compilers come up with their
>> 	own pragmas that can turn off certain optimizations where they
>> 	will be destructive."  In other words, let each implementer
>> 	add "volatile" in her own way.  However, the semantics of
>> 	"volatile" are well-defined and broadly useful.  Making its
>> 	use non-portable is gratuitous.
>
>This is silly.  If ANSI thinks they can redefine C, why should #pragma be
>an effort in imagination?  Couldn't they say 'hey... use this'?

same difference, except that normally '#' stuff is handled by the
preprocessor, and 'volatile' as a keyword would be available as part of
the type in much the same way as 'unsigned'. Compilers with optimisers
that do not assume nonvolatile variables are free to ignore the keyword,
since it has no bearing on their output.
-- 
   Greg Limes [limes@sun.com]				frames to /dev/fb

tim@amdcad.AMD.COM (Tim Olson) (05/01/88)

In article <51432@sun.uucp> limes@sun.UUCP (Greg Limes) writes:
| In article <503@wsccs.UUCP> terry@wsccs.UUCP (Every system needs one) writes:
| >This is the method one should use to determine if code is "bad"... but I
| >suggest you do not use a SUN 400* (matches all SUN 400 series) as your Sun,
| >as some of the assumptions it makes are _NOT_ K&R.
| 
| Yes, the Sun-4 systems have somewhat tighter restrictions than most
| previous archetectures. I would have been much happier if the hardware
| supported fixup of misaligned accesses, much like the 68020 supports
| arbitrarily aligned accesses. On the other hand, I do not remember K&R
| saying anything about arbitrary alignment of large storage cells. A
| quick look through the book, in fact, shows not only a lack of this
| assumption but also careful coding in the storage allocator (section
| 8.7, starting page 173 in my book) to assure that allocated blocks are
| properly aligned; it is assumed that, since the function returns a
| pointer to a character, the compiler will convert from (char *) to
| whatever type (foo *) the user wants.

In fact, K&R explicitly talk about alignment restrictions in many
places.  All you have to do is look in the index under (surprise)
"alignment restriction" to see the many discussions about it.

There is little doubt as to why DMR so carefully mentioned these
restrictions: the original C compiler was written for the PDP-11, which
had word accesses restricted to even-byte boundaries.  In fact, at least
3 of the four machines mentioned in K&R (PDP-11, IBM 360, and the Honeywell
6000) had such restrictions.

Perhaps Mr. Lambert would like to clarify what he means by "some of the
assumptions it makes are _NOT_ K&R"?

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

cudcv@daisy.warwick.ac.uk (Rob McMahon) (05/03/88)

In article <503@wsccs.UUCP> terry@wsccs.UUCP (Every system needs one) writes:
>In article <2003@rtech.UUCP>, jas@llama.rtech.UUCP (Jim Shankland) writes:
>> To get back
>> to "volatile":  it provides a portable way to declare storage objects
>> that may change without notice, and thus is useful in writing portable
>> (not necessarily portable *everywhere*, but plenty portable for may uses)
>> programs that access device registers, use shared memory, signal handlers,
>> etc. (we've been over the whole list).
>
>yes, it's a nice toy on rare ocassion, but that's why #pragma was invented.

It's been said before, but some people seem to have missed it ... how do
you use #pragma to specify all of:

	volatile int *p;
	int *volatile p;
	volatile int *volatile p;

?
-- 
UUCP:   ...!mcvax!ukc!warwick!cudcv	PHONE:  +44 203 523037
JANET:  cudcv@uk.ac.warwick.cu          ARPA:   cudcv@cu.warwick.ac.uk
Rob McMahon, Computing Services, Warwick University, Coventry CV4 7AL, England

ado@elsie.UUCP (Arthur David Olson) (05/04/88)

> It's been said before, but some people seem to have missed it ... how do
> you use #pragma to specify all of:
> 
> 	volatile int *p;
> 	int *volatile p;
> 	volatile int *volatile p;

#pragma	volatile int *p;
#pragma	int *volatile p;
#pragma	volatile int *volatile p;
-- 
	ado@ncifcrf.gov			ADO is a trademark of Ampex.

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

In article <536@sol.warwick.ac.uk> cudcv@cu.warwick.ac.uk (Rob McMahon) writes:
<>It's been said before, but some people seem to have missed it ... how do
<>you use #pragma to specify all of:
<>
<>	volatile int *p;

#pragma volatile int *p

<>	int *volatile p;

#pragma int *volatile p

<>	volatile int *volatile p;

#pragma volatile int *volatile p

To decrease redundancy use a place-holder token where it says "int"
above:

     #pragma volatile ? *p
     #pragma ? *volatile p
     #pragma volatile ? *volatile p

Or, simplest of all, just choose one of these:

     #pragma volatile *p
     #pragma volatile p
     #pragma volatile p, *p

P.S.  I still think the "volatile" keyword is a better way for
specifying volatility than the pragma mechanism, but not because of the
argument that I'm refuting.  There are two more serious problems with
using pragma here, and at least the second one has been mentioned
before in this newsgroup:  (1) The presence of "volatile" changes the
semantics of the hypothetical C virtual machine;  (2) Vendors are free
to choose any syntax for their #pragma volatile, violating the
intuitively-obvious requirement that a universal concept ought to be
represented in a universal syntax.

Standard Weasel Clause:  The validity of argument (1) above depends on
the exact meaning of the phrase "semantics of the hypothetical C
virtual machine.
-- 
Rahul Dhesi         UUCP:  <backbones>!{iuvax,pur-ee,uunet}!bsu-cs!dhesi

friedl@vsi.UUCP (Stephen J. Friedl) (05/05/88)

Rahul Dhesi says:
< Rob McMahon says:
< <>
< <> It's been said before, but some people seem to have missed it ...
< <> how do you use #pragma to specify all of:
< <>
< <>	volatile int *p;
< 
< #pragma volatile int *p
< 
< <>	int *volatile p;
< 
< #pragma int *volatile p

What about:

	typedef struct xxx vector;

	......

	#pragma vector *volatile p;

Is there any chance that a vendor might want to reserve a couple
of #pragmas for other uses besides volatile declarations :-)?

-- 
Steve Friedl    V-Systems, Inc. (714) 545-6442    3B2-kind-of-guy
friedl@vsi.com    {backbones}!vsi.com!friedl   attmail!vsi!friedl

limes@sun.uucp (Greg Limes) (05/06/88)

In article <536@sol.warwick.ac.uk> cudcv@cu.warwick.ac.uk (Rob McMahon) writes:
>It's been said before, but some people seem to have missed it ... how do
>you use #pragma to specify all of:
>
>	volatile int *p;
>	int *volatile p;
>	volatile int *volatile p;

It's been said before, but some people seem to have missed it ...

	volatile int *p;		-> #pragma volatile (*p)
	int *volatile p;		-> #pragma volatile (p)
	volatile int *volatile p;	-> #pragma volatile (p, *p)

Lets have volatile in the language, but not for the wrong reasons.
-- 
   Greg Limes [limes@sun.com]			Illigitimi Non Carborundum

throopw@xyzzy.UUCP (Wayne A. Throop) (05/06/88)

> cudcv@daisy.warwick.ac.uk (Rob McMahon)
>> terry@wsccs.UUCP (Every system needs one)
>> [...doing things like "volatile" is...] why #pragma was invented.
> It's been said before, but some people seem to have missed it ... how do
> you use #pragma to specify all of:
> 	volatile int *p;
> 	int *volatile p;
> 	volatile int *volatile p;

I've made this reply before, but some people seem to have missed it...
you do it like so:

                using keywords:            using pragmas:

  int is        volatile int *p;           int *p;
  volatile                                 #pragma volatile *p

  pointer is    int *volatile p;           int *p;
  volatile                                 #pragma volatile p

  both are      volatile int *volatile p;  int *p;
  volatile                                 #pragma volatile p, *p


"It works for me."

--
He wonders if he too might have made a similar mistake.
        --- "Seen and Not Seen" by Talking Heads from "Remain in Light"
-- 
Wayne Throop      <the-known-world>!mcnc!rti!xyzzy!throopw

cudcv@daisy.warwick.ac.uk (Rob McMahon) (05/07/88)

In article <8051@elsie.UUCP> ado@elsie.UUCP (Arthur David Olson) writes:
|[ I wrote ]
|> ... how do you use #pragma to specify all of:
|> 	volatile int *p;
|> 	int *volatile p;
|> 	volatile int *volatile p;
|#pragma	volatile int *p;
|#pragma	int *volatile p;
|#pragma	volatile int *volatile p;

Right, I'd forgotten how completely undefined #pragma's were.  Rats.  I
knew I should have stayed well clear of this discussion.

Rob
-- 
UUCP:   ...!mcvax!ukc!warwick!cudcv	PHONE:  +44 203 523037
JANET:  cudcv@uk.ac.warwick.cu          ARPA:   cudcv@cu.warwick.ac.uk
Rob McMahon, Computing Services, Warwick University, Coventry CV4 7AL, England

terry@wsccs.UUCP (Every system needs one) (05/14/88)

[ ut-oh.  They got me started on SPARC again...]

In article <503@wsccs.UUCP> I write:
| >This is the method one should use to determine if code is "bad"... but I
| >suggest you do not use a SUN 400* (matches all SUN 400 series) as your Sun,
| >as some of the assumptions it makes are _NOT_ K&R.

In article <51432@sun.uucp> limes@sun.UUCP (Greg Limes) replies (with no
tendency toward jingoism, considering his address?):
| Yes, the Sun-4 systems have somewhat tighter restrictions than most
| previous archetectures. I would have been much happier if the hardware
| supported fixup of misaligned accesses, much like the 68020 supports
| arbitrarily aligned accesses. On the other hand, I do not remember K&R
| saying anything about arbitrary alignment of large storage cells. A
| quick look through the book, in fact, shows not only a lack of this
| assumption but also careful coding in the storage allocator (section
| 8.7, starting page 173 in my book) to assure that allocated blocks are
| properly aligned; it is assumed that, since the function returns a
| pointer to a character, the compiler will convert from (char *) to
| whatever type (foo *) the user wants.

In article <21365@amdcad.AMD.COM>, tim@amdcad.AMD.COM (Tim Olson) makes
the assumtion that Greg is referring to some comments I made about how
"structure alignment is discussed in K&R", and goes on to lambast me:
> In fact, K&R explicitly talk about alignment restrictions in many
> places.  All you have to do is look in the index under (surprise)
> "alignment restriction" to see the many discussions about it.
> 
> There is little doubt as to why DMR so carefully mentioned these
> restrictions: the original C compiler was written for the PDP-11, which
> had word accesses restricted to even-byte boundaries.  In fact, at least
> 3 of the four machines mentioned in K&R (PDP-11, IBM 360, and the Honeywell
> 6000) had such restrictions.
> 
> Perhaps Mr. Lambert would like to clarify what he means by "some of the
> assumptions it makes are _NOT_ K&R"?

Yes, Perhaps he might.  Can you say VARARGS?

1) I can't write a printf() replacement that is always happy.
2) I can't write a main() which calls my_main() (I have this sort of fetish
   when it comes to being able to debug my programs) that is always happy.
3) '/* VARARGS */' is a comment used by lint, NOT a compiler directive.

Can you say alignment?

1) struct astruct *foo; foo = (astruct *)malloc( sizeof(struct astruct));
   doesn't always work when you have a large data segment or have to
   fix the stack size.
2) A struct should not have "random" holes, depending on word alignment,
   where it it necessary to have the first item in your struct be "word-sized"
   for sizeof( struct astruct) to return the actual length.  Otherwise, when
   you malloc(), the resultant pointer could be byte aligned, then have a
   "random" number of empty bytes if the structure were set up such that
   struct astruct { char fee; int fie;};.  This would cause such common code
   as a write() for sizeof(struct astruct) of a malloc'ed structure's contents
   to not work reliably.
3) int is the basic type in C.  Sign extension from something like the following
   int i;  char fum;
   i = (unsigned char)fum;
   can fail to properly handle the high(sign) bit, in that an extension can
   still occurr when it souldn't.
4) Due to cacheing and the methodlogy used to impliment pipes, pipes like
   to word-align their data.  An ioctl( TIOCQCNT); (or whatever the equivalent
   is on the bloody machine) can therefore return an incorrect count of the
   characters in a pipe if numchars%(sizeof(int)/sizeof(char))!=0.  This can
   be remedied using a flush, but that flush was NOT previously necessary.
5) A popen() of the line printer spooler wherein the program writes to the
   pipe to produce a report that doesn't stomp on other output (by snarfing
   /dev/lpr or whatever) and want's to avoid tmp files and child processes
   must also, by the same token, flush it's pipe before exiting, as a close
   will hang the process.

While these things are mostly OS bugs shown up by the architecture being too
close to the surface, or C compiler bugs generated by an effort to make the
architecture look fast.  It didn't fool me.

In the subset of C I program in, my programs will run on the SPARC.  But it
is a subset; SPARC should have been implemented such that the optimization
and "speed-up" decisions made in the compiler did not effect portability of
any code.  SPARC is not inherently bad; the aparrently marketing necessity
of implementing the C compiler such that it does stupid things IS bad.  If
it takes longer to compile a program, that is the price of SPARC.

Rather than grilling me with statements that say the combination of hardware
software which make up the C compiler environment ARE strictly K&R standard,
realise that:

	1) I do not cede that point; I don't think you can throw all of
	   the above out.  Maybe some, if I have typoed in an example or
	   if you are just trying to pick a fight, but not all.
	2) If I were to do so, it is still a bad decision for a company
	   to make it difficult to port to their machines.  I evidence
	   the HP-3000 and all those wonderful graphics programs for
	   the blockmode controllers on large IBM systems (I don't think
	   there are any)
	3) I know of at least 7 software companies who will not release
	   their products on the Sun systems SPARC as they have presently
	   implemented UNIX and C.  5 of them are winners of the "best of
	   UNIX software" awards, presented by UNIX WORLD magazine.

When you can say "yes" when your customer asks "does it run this", you can't
sell it.

When the customer calls their software vendor prior to buying a new machine
to make sure he can run "his programs", and there isn't a version for the
new machine, he won't buy the machine.

"The Bottom Line" IS the bottom line.


| Terry Lambert           UUCP: ...{ decvax, ihnp4 } ...utah-cs!century!terry |
| @ Century Software        OR: ...utah-cs!uplherc!sp7040!obie!wsccs!terry    |
| SLC, Utah                                                                   |
|                   These opinions are not my companies, but if you find them |
|                   useful, send a $20.00 donation to Brisbane Australia...   |
| 'Admit it!  You're just harrasing me because of the quote in my signature!' |

terry@wsccs.UUCP (Every system needs one) (05/14/88)

In article <51432@sun.uucp>, limes@sun.uucp (Greg Limes) writes:
> In article <503@wsccs.UUCP> terry@wsccs.UUCP (Every system needs one) writes:
> >This is the method one should use to determine if code is "bad"... but I
> >suggest you do not use a SUN 400* (matches all SUN 400 series) as your Sun,
> >as some of the assumptions it makes are _NOT_ K&R.
> 
> Gee. I have used Sun equipment for the last three years, followed their
> product line with avid interest for the last two, and worked there for
> the last six months ... and have never heard of the Sun 400. Since
> the hundreds digit tends to go up with power, and the top of the line
> that I am aware of (engineer, not salesman) is the Sun-4/280, the
> 400 series must really be something.
> 
> End sarcasm.

Yes, please do.  A hypothetical Sun 400 would not be "really something" if
it were based on SPARC and the UNIX and C compilers for SPARC, as currently
formulated.

UNIX and C on SPARC are like the skin of a starving dog.  They are not
pleasent to look at or talk to; they will bite you if given the chance;
the underlying structure pokes through, making it hard to recognise the
entire assembly for what it is supposed to be.

> Porting from a Vax to a Sun-3 uncovers lots of problems, mostly dealing
> with things like NULL pointer indirection; converting to a Sun-4
> uncovers even more, mostly dealing with alignment problems -- where an
> assumption is made about the lack of holes in structures, or specific
> layout of data memory. Maybe even some assumption is made of layout of
> function parameters in memory (on Sun4, they may not even BE there).

This is silly.  If you want, I will mail you an include file from software
that runs everywhere except SPARC. It is the machine.h, and has the names
of a hell of a lot of SUN competitors in it.  Any problems, therefore, by
weight of proven portabilty, would have to be the fault of the compiler
on the SPARC system.

> I try to code according to what appears to be the intent of K&R; after
> all, that is how I learned the language: read K&R, write something,
> compile it on an 11/50, make it work, think, read K&R, ...

This would imply that you code by "11/50 standard", NOT K&R.

> >> Perhaps that sounds like nitpicking; I don't think it is.  To get back
> >> to "volatile":  it provides a portable way to declare storage objects
> >> that may change without notice, and thus is useful in writing portable
> >> (not necessarily portable *everywhere*, but plenty portable for may uses)
> >> programs that access device registers, use shared memory, signal handlers,
> >> etc. (we've been over the whole list).
> >
> >yes, it's a nice toy on rare ocassion, but that's why #pragma was invented.
> 
> Have you ever written a device driver that had a top (mainline) half and
> a bottom (interrupt) half? Probably not. For you, "volatile" is a toy.

In working for a company whose sole product is communications software,
I have probably written more device drivers than you.  I have never been so
unsure of my ability in assembly to assume that an optimising C compiler
could write better code than me.  Consequently, I code in assembly for speed
on my bottom half, knowing full well that a lot of hardware designers do
stupid things that require software tradeoffs which by necessity are ugly.
Coding a driver which can not truly hope to be hardware independant on the
"bottom" half in a portable language rather than the fastest available
language is kludgy.  Why make portable something which by it's nature can
never be portable?

> For systems programming, and anybody who uses signal(), "volatile" is a
> requirement.

anybody who uses signal() on a VMS system realises that you get an access
violation if you use it past a number of constructs necessary for I/O,
including, but not limited to, event flags, which are by definition "volitile".

For systems programming, a compiler that is not too stupid to realize when
certain memory areas are uncached for memory-mapped I/O purposes is a bad
compiler to use and ill-fitted to the hardware it is intended for.  In short,
it needs work.  I am suggesting that the work be done by the compiler writers.

> Making it a part of the language forces the syntax to be
> the same across all systems that purport to support it; all others should
> give errors.

Gee, is that so I can use my VME bus drivers with my  Q bus?  Get real.

> >> 	we told them that we could have easily made our software 20-30%
> >> 	faster, but couldn't be bothered for such an inconsequential gain.
> >
> >	A: Don't tell them and keep your job.
> 
> Your customers are smarter than they look. Remember, if only one of a
> hundred picks up on this, and you have a thousand, someone will bring it
> up in a user's group meeting. Or, worse yet, some competitor will be 10%
> faster, causing a loss of that three billion dollar federal contract
> that was *so* important. If I can get a gain of 1%, I go for it.

Remember, also, the assumption was that the customers did not know.  Also,
remember that the context from which you removed this was a sarcastic
reply to the fallacious idea that it was impossible to tell when something
was volitile by having the compiler _look_ the right way.  Simply coding
into the compiler the rules which you yourself use to determine when to code
something volitile whould eliminate the need in the majority of cases.

> >> 	(3) "Let implementers of optimizing compilers come up with their
> >> 	own pragmas that can turn off certain optimizations where they
> >> 	will be destructive."  In other words, let each implementer
> >> 	add "volatile" in her own way.  However, the semantics of
> >> 	"volatile" are well-defined and broadly useful.  Making its
> >> 	use non-portable is gratuitous.
> >
> >This is silly.  If ANSI thinks they can redefine C, why should #pragma be
> >an effort in imagination?  Couldn't they say 'hey... use this'?
> 
> same difference, except that normally '#' stuff is handled by the
> preprocessor, and 'volatile' as a keyword would be available as part of
> the type in much the same way as 'unsigned'. Compilers with optimisers
> that do not assume nonvolatile variables are free to ignore the keyword,
> since it has no bearing on their output.

Except that I don't have to live with it if it's in the preprocessor.  If it's
"same difference", what's the bitch with putting it there?


Please do not take this as a condemnation of all Sun products.  Sun has a
long history of excellent hardware and software prior to SPARC, and I am
sure they will come to their senses and either rewrite the UNIX and/or the
compiler or simply can it.  Portability of new applications is not the
question; porting of older applications is.  It is more important that the
majority of code run rather than the minority of code running faster.  I am
just trying to do my part to hurry this day.


| Terry Lambert           UUCP: ...{ decvax, ihnp4 } ...utah-cs!century!terry |
| @ Century Software        OR: ...utah-cs!uplherc!sp7040!obie!wsccs!terry    |
| SLC, Utah                                                                   |
|                   These opinions are not my companies, but if you find them |
|                   useful, send a $20.00 donation to Brisbane Australia...   |
| 'Admit it!  You're just harrasing me because of the quote in my signature!' |

terry@wsccs.UUCP (Every system needs one) (05/17/88)

In article <536@sol.warwick.ac.uk>, cudcv@daisy.warwick.ac.uk (Rob McMahon) writes:
> It's been said before, but some people seem to have missed it ... how do
> you use #pragma to specify all of:
> 
> 	volatile int *p;
> 	int *volatile p;
> 	volatile int *volatile p;

You use different names and avoid overloading in the first place, since you
evidently realized that they don't all mean the same thing... or, you
get extremely clever in your definition of #pragma's through the use of
appropriate #define's.

				terry@wsccs

mouse@mcgill-vision.UUCP (der Mouse) (05/18/88)

In article <527@wsccs.UUCP>, terry@wsccs.UUCP (Every system needs one) writes:
> In article <51432@sun.uucp>, limes@sun.uucp (Greg Limes) writes:
>> Porting from a Vax to a Sun-3 uncovers lots of problems, [...];
>> converting to a Sun-4 uncovers even more, mostly dealing with
>> alignment problems -- where an assumption is made about the lack of
>> holes in structures, or [...].
> This is silly.  If you want, I will mail you an include file from
> software that runs everywhere except SPARC.

Well, I guess the code needs cleaning up a little then.

> Any problems, [...] by weight of proven portabilty, would have to be
> the fault of the compiler on the SPARC system.

What's special about SPARC?  Your code initially ran on some machines
X, Y, and Z; then you ported it to machine W and it needed some work
(it wasn't portable enough).  Now you go to port it to the SPARC and it
needs more work, and suddenly it's the machine rather than your code at
fault?  C doesn't guarantee nearly as much as most people seem to think.

>>>> [why volatile is good]
>>> yes, it's a nice toy on rare ocassion, but that's why #pragma was
>>> invented.
>> Have you ever written a device driver that had a top (mainline) half
>> and a bottom (interrupt) half?  [If not], "volatile" is a toy.
> [...] I have probably written more device drivers than you.  I have
> never been so unsure of my ability in assembly to assume that an
> optimising C compiler could write better code than me.

But don't assume that it can't, either.  Optimizer technology is very
good, and getting better all the time.

> Consequently, I code in assembly for speed on my bottom half, [...].
> Coding a driver which can not truly hope to be hardware independant
> on the "bottom" half in a portable language rather than the fastest
> available language is kludgy.  Why make portable something which by
> it's nature can never be portable?

So that it's readable and maintainable.  And portability means more
than "compiles without change elsewhere".  If I have a device driver
written for a Sun that implements some messy protocol over a parallel
port, and need a driver for a VAX that implements the same messy
protocol over a parallel port there, I'd much rather have to port a C
driver than an assembly driver.

> anybody who uses signal() on a VMS system realises that you get an
> access violation if you use it past a number of constructs necessary
> for I/O, including, [...].

Then I would say the VMS implementation is broken.

>> Making it a part of the language forces the syntax to be the same
>> across all systems that purport to support it; all others should
>> give errors.
> Gee, is that so I can use my VME bus drivers with my Q bus?

Yes.  See above.

> Simply coding into the compiler the rules which you yourself use to
> determine when to code something volitile whould eliminate the need
> in the majority of cases.

The compiler doesn't have as much information as you.  In the case of
most programmers, it is substantially less intelligent as well.

[someone suggests that volatile be a #pragma]
>> same difference, except that normally '#' stuff is handled by the
>> preprocessor, and 'volatile' as a keyword would be [...]
> Except that I don't have to live with it if it's in the preprocessor.
> If it's "same difference", what's the bitch with putting it there?

If the optimizer is such that it needs the hint provided by "volatile"
(pragma or keyword, whatever), then you can (a) turn off the optimizer,
or at least that part of it (which means most of it) or (b) never deal
with (write or modify) code that needs volatile.  Or get another
compiler, or take up knitting....  Your competitors will happily get a
compiler with a serious optimizer, use volatile, and blow by you
(unless you chose option (b)).

The only difference between using a #pragma for volatile and using a
keyword is one of uniformity.  People who aren't concerned with issues
of volatility can ignore it equally well in either form.  People who do
care would like to be able to use the same means everywhere.  (Can you
imagine the chaos that would result if each compiler had invented its
own syntax for declarations, say?)

					der Mouse

			uucp: mouse@mcgill-vision.uucp
			arpa: mouse@larry.mcrcim.mcgill.edu

ok@quintus.UUCP (Richard A. O'Keefe) (05/18/88)

In article <525@wsccs.UUCP>, terry@wsccs.UUCP (Every system needs one) writes:
> [ ut-oh.  They got me started on SPARC again...]
> In article <503@wsccs.UUCP> (he wrote):
> | >This is the method one should use to determine if code is "bad"... but I
> | >suggest you do not use a SUN 400* (matches all SUN 400 series) as your Sun,
> | >as some of the assumptions it makes are _NOT_ K&R.

> Can you say alignment?

The alignment requirements of the SPARC are *less* restrictive than
the requirements of Motorola's MC 88100.

-- 
--- 
ARPANET: quintus!ok@SUN.COM		| Logic programming:
UUCP:    ok@quintus.uucp		|   Prolog is only the beginning.
         ...!{sun,pyramid}!quintus!ok	| Elegance is not an option!