[comp.lang.c] noalias comments to X3J11

dmr@alice.UUCP (03/20/88)

Reproduced below is the long essay I sent as an official comment
to X3J11.  It is in two parts; the first points out some problems
in the current definition of `const,' and the second is a diatribe
about `noalias.'

By way of introduction, the important thing about `const' is that the
current wording says, in section 3.3.4, that a pointer to a
const-qualified object may be cast to a pointer to the plain object,
but "If an attempt is made to modify the pointed-to object by means of
the converted pointer, the behavior is undefined."  Because function
prototypes tend to convert your pointers to const-qualified pointers,
difficulties arise.

In discussion with various X3J11 members, I learned that this section
is now regarded as an inadvertant error, and no one thinks that
it will last in its current form.  Nevertheless, it seemed wisest
to keep my comments in their original strong form.  The intentions
of the committee are irrelevant; only their document matters.

The second part of the essay is about noalias as such.  It seems likely
that even the intentions of the committee on this subject are confused.

Here's the jeremiad.

				Dennis Ritchie
				research!dmr
				dmr@research.att.com
----------

This is an essay on why I do not like X3J11 type qualifiers.
It is my own opinion; I am not speaking for AT&T.

     Let me begin by saying that I'm not convinced that even
the pre-December qualifiers (`const' and `volatile') carry
their weight; I suspect that what they add to the cost of
learning and using the language is not repaid in greater
expressiveness.  `Volatile,' in particular, is a frill for
esoteric applications, and much better expressed by other
means.  Its chief virtue is that nearly everyone can forget
about it.  `Const' is simultaneously more useful and more
obtrusive; you can't avoid learning about it, because of its
presence in the library interface.  Nevertheless, I don't
argue for the extirpation of qualifiers, if only because it
is too late.

     The fundamental problem is that it is not possible to
write real programs using the X3J11 definition of C.  The
committee has created an unreal language that no one can or
will actually use.  While the problems of `const' may owe to
careless drafting of the specification, `noalias' is an
altogether mistaken notion, and must not survive.

1.  The qualifiers create an inconsistent language

     A substantial fraction of the library cannot be
expressed in the proposed language.

     One of the simplest routines,

        char *strchr(const noalias char *s, int c);

can return its first parameter.  This first parameter must
be declared with `const noalias;' otherwise, it would be
illegal (by the constraints on assignment, 3.3.16.1) to pass
the address of a const or noalias object.  That is, the type
qualifiers in the prototype are not merely an optional
pleasantry of the interface; they are required, if one is to
pass some kinds of data to this or most other library routines.

     Unfortunately, there is no way in X3J11's language for
strchr to return the value it promises to, because of the
semantics of return (3.6.6.4) and casts (3.3.4).  Whether
the stripping of the const and noalias qualifiers is done by
cast inside strchr, or implicitly by its return statement,
strchr returns a pointer that (because of `const') cannot be
stored through, and (because of `noalias') cannot even be
dereferenced; by the rules, it is useless.  (Incidentally, I
think this observation was made by Tom Plum several years
ago; it's disconcerting that the inconsistency remains.)

     Although the plain words of the Standard deny it, plastering
the appropriate `non-const' cast on an expression to
silence a compiler is sometimes safe, because the most probable
implementation of `const' objects will allow them to be
read through any access path, and will diagnose attempts to
change them by generating an access violation fault at run
time.  That is, in common implementations, adding or taking
away the `const' qualifier of a pointer can never create any
bugs not implicit in the rule `do not modify a genuine const
object through any access path.'

     Nevertheless, I must emphasize that this is NOT the
rule that X3J11 has written, and that its library is inconsistent
with its language.  Someone writing an interpreter
using X3J11/88-001 is perfectly at liberty to (indeed, is
advised to) carry with each pointer a `modifiable' bit, that
(following 3.3.4) remains off when a pointer to a const-
qualified object is cast into a plain pointer.  This implementation
will prevent many of the real uses of strchr, for
example.  I'm thinking of things like

        if (p = strchr(q, '/'))
                *p = ' ';

which are common and innocuous in C, but undefined by
X3J11's language.

     A related observation is that string literals are not
of type `array of const char.'  Indeed, the Rationale (88-004
version) says, `However, string literals do not have
[this type], in order to avoid the problems of pointer type
checking, particularly with library functions....'  Should
this bald statement be considered anything other than an
admission that X3J11's rules are screwy?  It is ludicrous
that the committee introduces the `const' qualifier, and
also makes strings unwritable, yet is unable to connect the
two conceptions.

2. Noalias is an abomination

     `Noalias' is much more dangerous; the committee is
planting timebombs that are sure to explode in people's
faces.  Assigning an ordinary pointer to a pointer to a
`noalias' object is a license for the compiler to undertake
aggressive optimizations that are completely legal by the
committee's rules, but make hash of apparently safe
programs.  Again, the problem is most visible in the
library; parameters declared `noalias type *' are especially
problematical.

     In order to write such a library routine using the new
parameter declarations, it is in practice necessary to
violate 3.3.4: `A pointer to a noalias-qualified type ...
may be converted to ... the non-noalias-qualified type.  If
the pointed to object is referred to by means of the converted
pointer, the behavior is undefined.'  Thus, the problem
that occurs with `const' is now much worse; there are no
interesting and legal uses of strchr.

     How do you code a routine whose prototype specifies a
noalias pointer?  If you fail to violate 3.3.4, but instead
try to rewrite the declarations of temporary variables to
make them agree in type with parameters, it becomes hard to
be sure that the routine works.  Consider the specification
of strtok:

        char *strtok(noalias char *s1, noalias const char *s2);

It retains a static pointer to its writable, `noalias' first
argument.  Can you be sure that this routine can be made
safe under the rules?  I have studied it, and the answer is
conditionally yes, provided one accepts certain parts of the
Standard as gospel (for example that `noalias' handles will
NOT be synchronized at certain times) while ignoring other
parts.  It is a very dodgy thing.  For other routines, it is
certain that complete rewriting is necessary: qsort, for
example, is full of pointers that rove the argument array
and change it here and there.  If these local pointers are
qualified with `noalias,' they may all be pointing to different
virtual copies of parts of the array; in any event,
the argument itself may have a virtual object that might be
completely untouched by the attempt to sort it.

     The `noalias' rules have the assignment and cast restrictions
backwards.  Assigning a plain pointer to a const-
qualified pointer (pc = p) is well-defined by the rules and
is safe, in that it restricts what you can do with pc. The
other way around (p = pc) is forbidden, presumably because
it creates a writable access path to an unwritable object.
With `noalias,' the rules are the same (pna = p is OK,
p = pna is forbidden), but the realistic safety requirements are
completely different.  Both of these assignments are equally
suspicious, in that both create two access paths to an
object, one manifestation of which might be virtual.

     Here is another way of observing the asymmetry: the
presence of `const type *' in a parameter list is a useful
piece of interface information, but `noalias type *' most
assuredly is not.  Given the declaration


        memcpy(noalias void *s1, const noalias void *s2, size_t n);

what information can one glean from it?  Some committee
members apparently believe that it conveys either to the
reader or to the compiler that the routine is safe, provided
that the strings do not overlap.  They are mistaken.
Perhaps the committee's intent is not reflected in the
current words of the Standard, but I can find nothing there
that justifies their belief.  The rules (page 65, lines 19-20)
specify `all objects accessible by these [noalias]
lvalues,' which is the entirety of both array arguments.

     More generally, suppose I see a prototype

        char *magicfunction(noalias char *, noalias char *);

Is there anything at all I can conclude about the requirements
of magicfunction? Is there anything at all I can conclude
about things it promises to do or not to do?  All I
learn from the Rationale (page 52) is that such a routine
enjoins me from letting the arguments overlap, but this is
at variance with the Standard, which gives a stronger
injunction.

     Within the function itself, things are equally bad.  A
`const type *' parameter, though it presents problems for
strchr and other routines, does usefully constrain the function:
it's not allowed to store through the pointer.  However,
within a function with a `noalias type *' parameter,
nothing is gained except bizarre restrictions: it can't cast
the parameter to a plain pointer, and it can't assign the
parameter to another noalias pointer without creating
unwanted handles and potential virtual objects.  The interface
MUST say noalias, or at any rate DOES say noalias, so
the author of the routine has all the grotesque inventions
of 3.5.3 (handles, virtual objects) rubbed in his face, like
or not.

     The utter wrongness of `noalias' is that the information
it seeks to convey is not a property of an object at
all.  `Const,' for all its technical faults, is at least a
genuine property of objects; `noalias' is not, and the
committee's confused attempt to improve optimization by pinning
a new qualifier on objects spoils the language.
`Noalias' is a bogus invention that is not necessary, and
not in any case sufficient for its apparent purpose.

     Earlier languages flirted with gizmos intended to help
optimization, and generally abandoned them.  The original
Fortran, for example, had a FREQUENCY statement that didn't
help much, confused people, and was dropped.  PL/1 had
`normal/abnormal' and `uses/sets' attributes that suffered a
similar fate.  Today, these are generally looked on as
adolescent experiments.

     On the other hand, the insufficiency of `noalias' is
suggested by Cray's Fortran compiler, which has 20 separate
keywords that control various details of optimization.  They
are specified by an equivalent of #pragma, and thus, despite
their oddness, can be ignored when trying to understand the
meaning of a program.

     Perhaps there is some reason to provide a mechanism for
asserting, in a particular patch of code, that the compiler
is free to make optimistic assumptions about the kinds of
aliasing that can occur.  I don't know any acceptable way of
changing the language specification to express the possibility
of this kind of optimization, and I don't know how much
performance improvement is likely to result.  I would
encourage compiler-writers to experiment with extensions, by
#pragma or otherwise, to see what ideas and improvements
they can come up with, but I am certain that nothing resembling
the noalias proposal should be in the Standard.

3.  The cost of inconsistency

     K&R C has one important internal contradiction
(variadic functions are forbidden, yet printf exists) and
one important divergence between rule and reality (common
vs. ref/def external data definitions).  These contradictions
have been an embarrassment to me throughout the years,
and resolving them was high on X3J11's agenda.  X3J11 did
manage to come up with an adequate, if awkward, solution to
the first problem.  Their solution to the second was the
same as mine (make a rule, then issue a blanket license to
violate it).

     I'm aware that there are distinctions to be made
between `conforming' and `strictly conforming' programs.
Although the X3J11 rules for qualifiers are inconsistent,
and therefore most nominally X3J11 compilers will ignore, or
only warn about, casts and assignments that X3J11 says are
undefined, people will somehow survive.  C has, after all,
survived the vararg and the extern problems.

     Nevertheless, I advise strongly against sanctifying a
language specification that no one can possibly embody in a
useful compiler.  This advice is based on bitter experience.

4.  What to do?

     Noalias must go.  This is non-negotiable.

     It must not be reworded, reformulated or reinvented.
The draft's description is badly flawed, but that is not the
problem.  The concept is wrong from start to finish.  It
negates every brave promise X3J11 ever made about codifying
existing practices, preserving the existing body of code,
and keeping (dare I say it?) `the spirit of C.'

     Const has two virtues: putting things in read-only
memory, and expressing interface restrictions.  For example,
saying

        char *strchr(const char *s, int c);

is a reasonable way of expressing that the routine cannot
change the object referred to by its first argument.  I
think that minor changes in wording preserve the virtues,
yet eliminate the contradictions in the current scheme.

1)   Reword page 47, lines 3-5 of 3.3.4 (Cast operators), to
     remove the undefinedness of modifying pointed-to
     objects, or remove these lines altogether (since casting
     non-qualified to qualified isn't discussed explicitly
     either.)

2)   Rewrite the constraint on page 54, lines 14-15, to say
     that pointers may be assigned without taking qualifiers
     into account.

3)   Preserve all current constraints against modifying
     non-modifiable lvalues, that is things of manifestly
     const-qualified type.

4)   String literals have type `const char []'.

5)   Add a constraint (or discussion or example) to assignment
     that makes clear the illegality of assigning to an
     object whose actual type is const-qualified, no matter
     what access path is used.  There is a manifest constraint
     that is easy to check (left side is not const-
     qualified), but also a non-checkable constraint (left
     side is not secretly const-qualified).  The effect
     should be that converting between pointers to const-
     qualified and plain objects is legal and well-defined;
     avoiding assignment through pointers that derive ultimately
     from `const' objects is the programmer's responsibility.


     These rules give up a certain amount of checking, but
they save the consistency of the language.

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

In article <7753@alice.UUCP>, dmr@alice.UUCP (Dennis Ritchie) writes:
> 4.  What to do?
> 
>      Noalias must go.  This is non-negotiable.
> 
>      It must not be reworded, reformulated or reinvented.
> The draft's description is badly flawed, but that is not the
> problem.  The concept is wrong from start to finish.  It
> negates every brave promise X3J11 ever made about codifying
> existing practices, preserving the existing body of code,
> and keeping (dare I say it?) `the spirit of C.'

Now >>this<< is a man who does not mince his words.

-- 
Steve Friedl              V-Systems, Inc.            *Hi Mom*
friedl@vsi.com  {uunet,attmail,ihnp4!amdcad!uport}!vsi!friedl

swarbric@tramp.Colorado.EDU (Frank Swarbrick) (03/22/88)

What does this const thing have to do with the function below getting the
suspicious pointer conversion warning?

int pos(const char *str,char c)
{
 char *s;
 
 s = strchr(str,c);
 return s ? (int)(s - str) : -1;
}

This, of course, works if I take out the const thing.  Is this one of the
things that you were complaining about, or should this just plain not work?
(This was done in Turbo C 1.5, by the way.)

Frank Swarbrick (and his cat)
swarbric@tramp.UUCP               swarbric@tramp.Colorado.EDU
...!{ncar|nbires}!boulder!tramp!swarbric
"Welcome back my friends to the show that never ends..."

PEPRBV%CFAAMP.BITNET@husc6.harvard.EDU (Bob Babcock) (03/23/88)

>>`Volatile,' in particular, is a frill for
>>esoteric applications, and much better expressed by other
>>means.  Its chief virtue is that nearly everyone can forget
>>about it.

What about an interrupt routine which receives control on a keyboard
interrupt and sets a globally known flag.  That doesn't sound very
esoteric to me, and volatile seems exactly what is needed to describe
such a flag to the compiler.  (I also do some of my coding in an
environment where some variables are hardware registers which may
change due to external events.  That's less common, but I wouldn't
call it esoteric either.)

henry@utzoo.uucp (Henry Spencer) (03/24/88)

>What does this const thing have to do with the function below getting the
>suspicious pointer conversion warning?
>
> return s ? (int)(s - str) : -1;

You're mixing two separate types of pointer:  s is char *, str is
const char *.  THOSE ARE NOT THE SAME TYPE.  Evidently the compiler
is doing the conversion for you, but it's not entirely happy about it.
In this particular case, adding const to the declaration of s would
fix it, pretty much.  (The exact rules for this sort of thing may yet
change again before ANSI C is final.)
-- 
"Noalias must go.  This is           |  Henry Spencer @ U of Toronto Zoology
non-negotiable."  --DMR              | {allegra,ihnp4,decvax,utai}!utzoo!henry

swarbric@tramp.Colorado.EDU (Frank Swarbrick) (03/25/88)

In article <1988Mar23.193330.459@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
:>What does this const thing have to do with the function below getting the
:>suspicious pointer conversion warning?
:>
:> return s ? (int)(s - str) : -1;
:
:You're mixing two separate types of pointer:  s is char *, str is
:const char *.  THOSE ARE NOT THE SAME TYPE.  Evidently the compiler
:is doing the conversion for you, but it's not entirely happy about it.
:In this particular case, adding const to the declaration of s would
:fix it, pretty much.  (The exact rules for this sort of thing may yet
:change again before ANSI C is final.)

I just changed it to
  return s ? s - (char *)str : -1;

and it worked fine.  Thanks for the idea, although you gave it indirectly and
maybe without knowing it...

(Actually I didn't run it, but it compiled without giving the warning.)

Frank Swarbrick (and his cat)
swarbric@tramp.UUCP               swarbric@tramp.Colorado.EDU
...!{ncar|nbires}!boulder!tramp!swarbric
"Remember when you were young.  You shown like the sun..."

tom@hcx2.SSD.HARRIS.COM (03/25/88)

>     Const has two virtues: putting things in read-only
>memory, and expressing interface restrictions.  For example,
>saying
>
>        char *strchr(const char *s, int c);
>
>is a reasonable way of expressing that the routine cannot
>change the object referred to by its first argument.  I
>think that minor changes in wording preserve the virtues,
>yet eliminate the contradictions in the current scheme.

You bet!, That would be a very reasonable thing for const to do,
and that's what I thought it did until I talked to my friend on
the committee. It is obvious to the casual observer what something
being constant means, right? But no, the obvious meaning of const
is not acceptable to some committee members, so what happens, `noalias'
is invented just so `noalias const' can mean what just `const'
should obviously have meant all along.

I agree with dmr, noalias must go! But I have another even more
pressing reason for getting rid of it. Working for a compiler
vendor, this is the nightmare scenario I see:

   1) User with non-optimizing compiler sees noalias and says
      `This is neat! I can get my code really optimized with this!'
      and proceeds to use it liberally throughout the 40,000,000
      lines of code he develops with his nonoptimizing compiler
      that is toatlly bored by `noalias'.

   2) User switches to our highly optimizing compiler which immediately
      deletes 30,000,000 lines of apparently dead code. And does
      nastly transformations to the rest of it.

   3) User screams, yells, and generally makes life totally
      miserable complaining about how our compiler is broken.

Repeat this over and over for an endless series of users who won't
believe they can't write code. Not to mention that some of the
problems might be actual bugs in the optimizer, but it could
take weeks to track them down and sort them out.

For this reason alone, I can't believe that any vendor is likely to
actually take advantage of any optimizations that noalias might allow.
Similar situations already exist for FORTRAN. There are all sorts
of optimizations allowed according to the strict letter of the
FORTRAN standard, but very few compilers will do them by default because too
much user code will break. You generally have to specifically request
the highest level of optimization.

This is an important point. Real vendors have to develop compilers
for real users. Neither users or compilers are perfect, and `noalias'
will just emphasize those imperfections.

The correct way to aggressively optimize programs is via a global
program database that gathers the information for the whole
program and *knows* what is aliased and what is not, but thats
another story....
================================
tahorsley@ssd.harris.com

henry@utzoo.uucp (Henry Spencer) (03/26/88)

>>`Volatile,' in particular, is a frill for esoteric applications...
>
> What about an interrupt routine which receives control on a keyboard
> interrupt and sets a globally known flag.  That doesn't sound very
> esoteric to me...

Interrupt routines are almost by definition esoteric, not to mention highly
machine-specific.  Only on PCs do users commonly write their own interrupt
routines; in more modern environments [MSDOS is a Neanderthal operating
system, its only saving grace being some of the nifty applications that run
on it] such things generally are confined to the bowels of the operating
system, where they belong.
-- 
"Noalias must go.  This is           |  Henry Spencer @ U of Toronto Zoology
non-negotiable."  --DMR              | {allegra,ihnp4,decvax,utai}!utzoo!henry

jesup@pawl21.pawl.rpi.edu (Randell E. Jesup) (03/27/88)

In article <1988Mar25.172355.348@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
>>>`Volatile,' in particular, is a frill for esoteric applications...
>
>Interrupt routines are almost by definition esoteric, not to mention highly
>machine-specific.  Only on PCs do users commonly write their own interrupt
>routines; in more modern environments [MSDOS is a Neanderthal operating
>system, its only saving grace being some of the nifty applications that run
>on it] such things generally are confined to the bowels of the operating
>system, where they belong.

	And would you mandate that C never be used for writing operating
systems (one of it's original purposes)?  What about user programs that deal
with custom or non-standard hardware (like lab stuff)?  Or things like
the Amiga, where you can have your message ports handled by software interrupts
if you prefer them to signals.
	'Volatile' is extremely important for dealing with real-world
hardware.  The contortions to work without it in these cases are horrible,
while it is a relatively easy thing to deal with if you don't need it (ignore
it).  The fact that things that need volatile probably won't be portable
across all machines that have C compilers is a non-issue.

>"Noalias must go.  This is           |  Henry Spencer @ U of Toronto Zoology
>non-negotiable."  --DMR              | {allegra,ihnp4,decvax,utai}!utzoo!henry

 ^^^^^^^^^^^^^^^^
Now that we can agree on!

     //	Randell Jesup			      Lunge Software Development
    //	Dedicated Amiga Programmer            13 Frear Ave, Troy, NY 12180
 \\//	beowulf!lunge!jesup@steinmetz.UUCP    (518) 272-2942
  \/    (uunet!steinmetz!beowulf!lunge!jesup) BIX: rjesup

(-: The Few, The Proud, The Architects of the RPM40 40MIPS CMOS Micro :-)

jas@llama.rtech.UUCP (Jim Shankland) (03/28/88)

In article <1988Mar25.172355.348@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
>>>`Volatile,' in particular, is a frill for esoteric applications...
>>
>> What about an interrupt routine ....
>
>Interrupt routines are almost by definition esoteric, not to mention highly
>machine-specific.  Only on PCs do users commonly write their own interrupt
>routines....

Oh, all right, I'll rise to the bait.  What about shared memory applications?
Surely memory that can be written by another process at any time is volatile.
Do we really want to claim that all code addressing shared memory is part
of an "esoteric application"?
Jim Shankland
  ..!ihnp4!cpsc6a!\
               sun!rtech!jas
 ..!ucbvax!mtxinu!/

  > The preceding message was brought to you courtesy of Eddie       <
  > Enterprises, a broadly diversified, multinational corporation    <
  > bringing software, roofing supplies, exquisite keyboard sounds,  <
  > and other fine products to a hungry world.                       <

rcvie@tuvie (ELIN Forsch.z.) (03/28/88)

In article <1988Mar25.172355.348@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
>Interrupt routines are almost by definition esoteric, not to mention highly
>machine-specific.

Signal handlers will be at least very similar to interrupt routines. Still it
does not seem to be esoteric to me, if I set a flag in such a handler. And now
please tell me, how to tell the compiler it must not `optimize' the access to
this flag?


		Dietmar Weickert,
			ALCATEL-ELIN Research Center, Vienna, Austria.

sef@csun.UUCP (Sean Fagan) (03/28/88)

In article <588@imagine.PAWL.RPI.EDU> beowulf!lunge!jesup@steinmetz.UUCP writes:
>In article <1988Mar25.172355.348@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
>>>>`Volatile,' in particular, is a frill for esoteric applications...
>>
>>Interrupt routines are almost by definition esoteric, not to mention highly
>>machine-specific.
>	'Volatile' is extremely important for dealing with real-world
>hardware.

Another use I haven't seen mentioned is for shared memory.  Since this can
be accessed (and modified) by more than one process, having a heavily
optimizing compiler move one location (or more) into a register would be a
bad idea.  Doing something like

	volatile char shm_seg[1024];
	shmat(...,shm_seg,...);

seems like it would be nice to have (I may have screwed up the syntax of the
shared memory stuff, pardon me).

>>"Noalias must go.  This is           |  Henry Spencer @ U of Toronto Zoology
>>non-negotiable."  --DMR              | {allegra,ihnp4,decvax,utai}!utzoo!henry
> ^^^^^^^^^^^^^^^^
>Now that we can agree on!
As has been stated before, when this man (dmr@alice) speaks, ANSI should
listen!

>     //	Randell Jesup			      Lunge Software Development
-- 

Sean Fagan                   uucp:   {ihnp4,hplabs,psivax}!csun!sef
CSUN Computer Center         BITNET: 1GTLSEF@CALSTATE
Northridge, CA 91330         (818) 885-2790

tneff@atpal.UUCP (Tom Neff) (03/28/88)

In article <1988Mar25.172355.348@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
>Interrupt routines are almost by definition esoteric, not to mention highly
>machine-specific.  Only on PCs do users commonly write their own interrupt
>routines...

It would be fairer to say "only on microcomputers" rather than "only on
PCs."  I write real-time systems for a living, and so do a lot of other
folks I know.  We do write interrupt routines, and plenty of 'em.  "C" is
a strong contender among languages for this work, because of its portability
and lack of overhead.  The basic concept of /volatile/ is very important to
me, and I'm glad XJ311 recognizes it.  Many's the time I have had to surround
a few statements with forests of labels or calls to dummy() just to get one
compiler or another to stop optimizing access to a location!

I will admit, though, that /vol/ is a grown-up keyword, which plenty of
programmers will have little use for.  But it needn't intrude in your lives
at all.  Those who need it, use it.  (Fortunately it's not too much of a pain
to implement -- effectively it just flags optimization off for certain
variables).  It does sound like /noalias/ is making a much noisier and messier
splash on its arrival in the standard.  I am not too keen on forcing a strange
new keyword into half the declarations, for instance, in dear old stdio.h. TMN


-- 

Tom Neff 

daveb@geac.UUCP (David Collier-Brown) (03/31/88)

In article <1988Mar25.172355.348@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
| Interrupt routines are almost by definition esoteric, not to mention highly
| machine-specific.

In article <597@tuvie> rcvie@tuvie.UUCP (D. Weickert) writes:
| Signal handlers will be at least very similar to interrupt routines. Still it
| does not seem to be esoteric to me, if I set a flag in such a handler. And now
| please tell me, how to tell the compiler it must not `optimize' the access to
| this flag?

Well, they're interrupt-like in style, but not always in nature.  It
is probably true that some machine and operating system somewhere on
this net has signals which run asynchronously to the rest of the
program, but in general they are executed in the normal context of
a C program, as a (simulated, perhaps) subroutine call and strictly
synchronously with the rest of the program.  The CP/M machine I'm
using to write this posting from has signal handlers and dispatchers
in the great majority of its C programs: written by Drew Sullivan
(drew@lethe) many moons ago.

 And you don't, therefore have to do anything to the said flag
variable.  Except make it accessable.
-- 
 David Collier-Brown.                 {mnetor yunexus utgpu}!geac!daveb
 Geac Computers International Inc.,   |  Computer Science loses its
 350 Steelcase Road,Markham, Ontario, |  memory (if not its mind) 
 CANADA, L3R 1B3 (416) 475-0525 x3279 |  every 6 months.

henry@utzoo.uucp (Henry Spencer) (03/31/88)

> Signal handlers will be at least very similar to interrupt routines. ... it
> does not seem to be esoteric to me, if I set a flag in such a handler. ...
> ... how to tell the compiler it must not `optimize' the access to
> this flag?

It is very difficult to say much about what signal handlers can do safely.
Essentially the *one* thing that X3J11 guarantees is that they can set a
flag of type sig_atomic_t, an implementation-defined type that can have
any desired magic properties.
-- 
"Noalias must go.  This is           |  Henry Spencer @ U of Toronto Zoology
non-negotiable."  --DMR              | {allegra,ihnp4,decvax,utai}!utzoo!henry

sarima@gryphon.CTS.COM (Stan Friesen) (04/04/88)

In article <2518@geac.UUCP> daveb@geac.UUCP (David Collier-Brown) writes:
>
>
>In article <597@tuvie> rcvie@tuvie.UUCP (D. Weickert) writes:
>|Signal handlers will be at least very similar to interrupt routines. Still it
>|does not seem to be esoteric to me, if I set a flag in such a handler. And now
>|please tell me, how to tell the compiler it must not `optimize' the access to
>|this flag?
>
>Well, they're interrupt-like in style, but not always in nature.  It
>is probably true that some machine and operating system somewhere on
>this net has signals which run asynchronously to the rest of the
>program, but in general they are executed in the normal context of
>a C program, as a (simulated, perhaps) subroutine call and strictly
>synchronously with the rest of the program.

	You and I seem to have a different definition of asynchronous! When I
use the term I mean that the timing of two routines in the system are
indeterminate relative to one another, *not* that only one is executing at any
given time. Yes most signal handlers are run as simulated subroutines in the
user context, BUT these pseudo-routines may be "called" at *any* time, such as
between a load and a store instruction. The programmer has no idea where the
'main' path will be executing when the handler is activated. THIS is what makes
handlers asynchronous, and what makes volatile necessary.

> And you don't, therefore have to do anything to the said flag
>variable.  Except make it accessable.

	Only if you do not use the -O flag! With optimization on the compiler
may decide that it has already loaded a value into a register and use the
cached value instead of loading fresh from the real variable. In the case
of a flag set by a signal handler this is *wrong*, since the handler may
have been called between the original load and the ultimate store. So
you do have to declare such variable'volatile', at least if you wish a
verifiably correct program.

flaps@dgp.toronto.edu (Alan J Rosenthal) (04/05/88)

beowulf!lunge!jesup@steinmetz.UUCP writes:
>The fact that things that need volatile probably won't be portable
>across all machines that have C compilers is a non-issue.

Hardly.  We're discussing a standard for portable C programs.
Compilers are free to accept non-conforming programs.[1]  Your Amiga C
compiler, IF it does optimizations of the kind that make `volatile'
useful, would provide a volatile keyword for use in system-level
programming whether or not it was required by the ANSI standard.[2]
However, it would be silly for the whole world of compiler writers to
have to recognize the volatile keyword, and take it into account while
doing optimizations, just because on the Amiga there are uses for it in
certain inherently non-portable programs.[3]

ajr
--

[1] Note that if the compiler doesn't allow a variable called
``volatile'' and the standard doesn't make this a reserved word, the
compiler is not conforming.  However, command-line options can control
this.  So can a #pragma.

[2] That's a big if.

[3] This is more of a floodgate than most people realize.  For example,
I can easily see the use, on the Amiga, for a type qualifier that
meant, for example, that in the expression "f(a,a)" the two a's must
have been obtained with the same (atomic) load instruction so that
their values are guaranteed identical.  Otherwise you have to turn off
context-switching, assign `a' to a temporary variable, and turn it on again.

-- 
"Comment, Spock?"
"Very bad poetry, Captain."

aglew@urbsdc.Urbana.Gould.COM (04/07/88)

>Interrupt routines are almost by definition esoteric, not to mention highly
>machine-specific.  Only on PCs do users commonly write their own interrupt
>routines; in more modern environments [MSDOS is a Neanderthal operating
>system, its only saving grace being some of the nifty applications that run
>on it] such things generally are confined to the bowels of the operating
>system, where they belong.

Strongly disagree. A decent signal interface should be comparable to
an interrupt routine. Too often is asynchronous communication neglected
in favour of synchronous IPC.


Andy "Krazy" Glew. Gould CSD-Urbana.    1101 E. University, Urbana, IL 61801   
    aglew@gould.com     	- preferred, if you have MX records
    aglew@xenurus.gould.com     - if you don't
    ...!ihnp4!uiucuxc!ccvaxa!aglew  - paths may still be the only way
   
My opinions are my own, and are not the opinions of my employer, or any
other organisation. I indicate my company only so that the reader may
account for any possible bias I may have towards our products.

henry@utzoo.uucp (Henry Spencer) (04/10/88)

> ... Too often is asynchronous communication neglected
> in favour of synchronous IPC.

With good reason, since it is much harder to use safely and correctly.
Note that the first thing most operating systems do is to turn the hardware's
asynchronous interrupts into some (at least semi-) synchronous form.
-- 
"Noalias must go.  This is           |  Henry Spencer @ U of Toronto Zoology
non-negotiable."  --DMR              | {allegra,ihnp4,decvax,utai}!utzoo!henry