So the standard says, they tell me. It is also one the more flagrant
violations of the Principle of Least Astonishment I've seen in a
while. In fact, while we're at it, it would seem to violate the idea
that you give the programmer all the rope she asks for, because she
just might be needing it to pull herself out of a bog. Gentlemen
system programmers, surely you too have algorithms that are more
accurately expressed with arrays from other than base zero?
Actually, on a segmented architecture I might be astonished if it
*didn't* bomb. The principle is rather subjective I'm afraid.
: In fact, while we're at it, it would seem to violate the idea
: that you give the programmer all the rope she asks for, because she
: just might be needing it to pull herself out of a bog.
Note that the standard does *not* say that you can't do this, it
just says that it is nonportable. So, unless this bog is a
portable bog, she (Ugh. I prefer s/h/it for a neutered pronoun :-)
won't need a portable rope!
: Gentlemen
: system programmers, surely you too have algorithms that are more
: accurately expressed with arrays from other than base zero?
Well, actually, no. One of the characteristics of being *very*
experienced with a language is that you tend to think of
solutions in terms of what that language most easily supplies.
Hmmmm. Now that I think about it, I do seem to recall some Shell
sort where a zero base made the code more complex.
However, since there *is* a portable way to do this (if you don't
mind the syntax), I'll show it.
func()
{
int foo_array[SIZE][SIZE];
#define foo(n,m) (foo_array[(n)-1][(m)-1])
...
}
Ugly, but it works. And it can be used to make the NR programs
portable.
---
Bill
novavax!proxftl!bill
Yes, certainly. However, if one wants such code to be portable, one must
be careful how one computes addresses into such arrays. The only fully
portable way to compute a[b] when you want "a" to start at subscript "s"
is a[b-s]. (a-s)[b] certainly is appealing, since it permits doing the
subtraction once rather than every time, but it is *NOT PORTABLE*. Thanks
primarily (but not exclusively) to Intel, it is not safe to back a pointer
up past the beginning of an array and then advance it again. C has never
guaranteed this to work; indeed, there have always been explicit warnings
that once the pointer goes outside the array, all bets are off. X3J11 has
legitimized pointers just past the end of an array, since this is very
common and is cheap to do, even on difficult machines, but the beginning
of an array remains an absolute barrier to portable pointers. This is
simply a fact of life in the portability game.
--
Intel CPUs are not defective, | Henry Spencer at U of Toronto Zoology
they just act that way. | uunet!attcan!utzoo!henry he...@zoo.toronto.edu
On a segmented architecture, like 8086's, malloc can and does return
a value that is a pointer to the beginning of a segment. That is, there
is a 16 bit selector and a 16 bit offset, the offset portion is 0 or a
very small number. Thus, subtracting a value from the pointer could result
in a segment wrap. Trouble occurs when you do things like:
array = malloc(MAX * sizeof(array[0]));
for (p = &array[MAX-1]; p >= &array[0]; p--)
...
The >= will fail, because the last p-- will cause an underflow and now
p is greater than &array[MAX]! I've encountered this many times in
porting code from Unix to PCs. The correct way to write the loop is:
for (p = &array[MAX]; p-- > &array[0]; )
or something similar.
Please, no flames about Intel's architecture. I've heard them all for years.
The best way to learn to write portable code is to be required to port
your applications to Vaxes, 68000s, and PCs. (I have all 3 on my desk!)
And VAX/VMS specifically. Until you've ported to VMS you haven't
ported. Really.
--
Rahul Dhesi UUCP: <backbones>!{iuvax,pur-ee,uunet}!bsu-cs!dhesi
We find that using 68000's (Suns and Macintoshes) and IBM-PC's
(in the various memory models) is sufficient to catch most
portability problems. Especially since we avoid as much as
possible using system provided libraries and do not do terminal
I/O except through standard I/O.
Anybody else have suggestions on sets of systems for checking
portability? And how about portability between different system
libraries and different terminal handling schemes, a problem we
don't (yet) have because we ignore it?
---
Bill
novavax!proxftl!bill
1) floating header files (where is struct mumble defined, where does
header file bletch.h live, etc.)
2) library differences (is it in libc, or libm, is it strchr or
rindex, does it exist or do I have to carry my own version along. . .)
3) Implementation problems (working around bugs in the system. . .)
4) Architecture dependencies due to language design or implementation
decisions left to the implementer. (it worked on my brand x, but
after I tried it on brand y, I went back and read K&R and sure
enough its not legal. . .)
The rude fact is that the first three can't be covered by any small
set of machines, although a fairly good aproximation can be made by
trying a System V machine, a BSD machine, an MS-DOS machine, and a non-
un*x machine. (VAX/VMS, Apollo)
As far as the fourth goes, I have been bitten by the following
collection of dumb assumptions:
1) byte ordering
2) word size
3) "all pointers are == char *"
4) calling stack implementation
5) assuming a linear address space without holes
My collection of machines which ring out these problems is fairly
small, but probably not widely accessable. I find that I can get by
with only three machines to cover all of the dumb assumptions: A Vax
11/780, a Cray 2, and an Silicon Graphics Iris 4D. The Cray system
seriously strains dumb assumptions in 1-3 and 5, and the Iris gets 4.
Without the 2, a much larger collection of machines would be needed,
but I suspect that a lot could be accomplished with an IBM PC and a
SUN-3 as an alternative.
Anyway, I don't assume that code I've written is reasonably portable,
until it compiles and appears to work on 16, 32 and 64 bit machines of
varying byte order, memory model and calling stack implementation, and
then I only assume that it is reasonably portable and that I've blown
it for the next class of machines I'm going to see. This is a very
healthy paranoia to develop.
Marty
+-+-+-+ I don't know who I am, why should you? +-+-+-+
| fo...@lemming.nas.nasa.gov |
| ...!ames!orville!fouts |
| Never attribute to malice what can be |
+-+-+-+ explained by incompetence. +-+-+-+
You forgot the best one: any '286 running SCO Xenix System V.
I like to refer to my machine as a portability test with a power switch.
--
Chip Salzenberg <ch...@ateng.uu.net> or <uunet!ateng!chip>
A T Engineering My employer may or may not agree with me.
The urgent leaves no time for the important.
int b[4], *bb = &b[-1];
and variations thereof are interdit, why not use
int bb[5];
Before I am flamed to death for wasting *four* *whole* *bytes* of memory,
I think I can claim excemption under the `speed-vs-space' banner.
Using a pointer as an array probably involves an extra instruction or
CPU cycle somewheres - and `#define bb(x) (b[(x)-1])' does countless
`invisible' subtractions...
pdc
No! That wasn't the problem! (Wish it was, that'd be easy to
avoid!).
The problem is that the authors of Numerical Recipes (NR) observe,
correctly, that many numerical problems are naturally non-zero based.
This gives you the choice between carrying around boatloads of index
arithmatic (inefficient and error-prone), or making non-zero based
arrays. They opt for the latter, in the following way:
float *my_vec; /* this is going to be a vector */
int nl, nh;
...
my_vec = vector( nl, nh ); /* allocates a vector with lowest valid
index nl, and highest valid index nh
*/
...
my_vec[3] = foo(bar);
...
Where we have:
float *vector( nl, nh )
int nl;
int nh;
{
float *v;
v = (float *)malloc( ( nh-nl +1 )* sizeof(float) );
if( v == 0 ) nrerror( "Allocation error in vector()" );
return v - nl;
}
This is quite a bit more disciplined than the example above; it is
also quite bit more fundamental. Fortunately, as far as I've checked
at least, NR only uses vectors and matrices with either 0 or unit
offset, so on broken architectures you could always do
malloc( (nh + 1 )* sizeof(float) );
return v;
This would waste a float per vector, and a pointer-to-float plus n
floats for an n-by-something matrix. Ugly, but it works. (and we
*are* the throw-away culture after all :-)
Rob Carriere
Sorry, but reality is sometimes astonishing.
That is not an X3J11 invention, just an acknowledgement of the
way the world is. (For example, segmented architectures.)
>Gentlemen >system programmers, surely you too have algorithms that are
>more accurately expressed with arrays from other than base zero?
I doubt that even lady system programmers have much trouble with
0-based arrays.
INcorrectly! I've written a lot of array/matrix code in both
Fortran and C, and have found that it normally doesn't matter
and in those cases where it does matter, it doesn't matter much.
I've known mathematicians who have switched over to starting
enumerating at 0 instead of 1. They argued that THAT was "more
natural". One can certainly get used to either convention.
--
-- David Dyer-Bennet
...!{rutgers!dayton | amdahl!ems | uunet!rosevax}!umn-cs!ns!ddb
d...@Lynx.MN.Org, ...{amdahl,hpda}!bungia!viper!ddb
Fidonet 1:282/341.0, (612) 721-8967 hst/2400/1200/300
Trivial refutation time! Surely it is obvious that ``numerical
problems'' forms a (large) superset of ``array/matrix code'' as far as
numerical analysis is concerned?
Believe it or not, but there are *many* algorithms out there where
it's either base-1 indexing or index arithmatic all over the place.
Not with your traditional LU-decomposition stuff and so on, but with
algorithms where the contents or properties of the matrix elements are
computed from the indeces.
Rob Carriere
Trivial indeed! If the code does not involve arrays/matrices,
the issue of 0-based or 1-based indexing doesn't even arise.
> Also, while I haven't tried it personally, I remember a LONG string of
>articles years ago in some group with the subject "Porting to PRIME seen
>as a probable negative experience"; I seem to remember it has to do with
>different types of pointers being of different sizes, none of which would
>fit in in an int.
This is somewhat of a bum rap. Prime C at one time had 48 bit
char pointers versus 32 bit word pointers. Currently all pointers are
48 bits. This makes for problems for people who blithely stuff pointers
into ints. But it really isn't a problem for people who port from UNIX
to PRIMOS who run their code through lint (and act on the results).
Primos C does have some oddities. They set the high bit on in
ascii chars. Setting a file pointer to stdin or stdout has to be done
at the top level. Library routines sometimes have different calling
sequences. There is a 128K limit on array sizes (machine architecture).
But it really isn't all that bad; I've never seen the C compiler break
on standard portable C which is more than I can say for VMS C.
--
In the fields of Hell where the grass grows high
Are the graves of dreams allowed to die.
Richard Harter, SMDS Inc.
I have used an Hewlett-Packard HP9000 model 500, which has a very
strange memory architecture (uses non-contiguous memory
segments), and a real stack (which means that uninitialized local variables
contain a zero). Emacs cannot run on it.
There exists a Pr1me system which always has the high bit
of each byte set, so ASCII runs from 128 to 255.
Of course, EBCDIC machines catch most of the programs which
avoided <ctype.h> but use ('a' <= x && x <= 'z') , and segmented
memory machines (like PC's with large model) catch all programs
that (mis)use ints and pointers and longs.
--
Johan
I would think Vaxes, IBM-PCs, Suns, and Macs are somewhat incestuous.
If you have the money and are interested in the market, you might try
some radically different hardware and operating systems like mainframe
IBM, Cray, CDC, Fujitsu,.....
From article <7...@ns.UUCP>, by d...@ns.UUCP (David Dyer-Bennet):
> No portability check is complete until you've tried some word-oriented
> rather than byte-oriented system. Preferrably something with a word-size
> not a multiple of 8 bits (like 60, or 36). CDC, Unisys, Honeywell, and of
> course the DEC PDP-10 series all come to mind.
Actually the 9-bit byte machines are fairly easy to port to: all
sorts of code of varying quality will run on the Honeywell-Bull
DPS-8 using the Waterloo C Compiler. Try a machine with funny
pointer lengths like the DPS-6, though... Its an 8-bit byte, but
char pointers are 48 bits and others are 32, if you use to high an
address the system will trap even loading a register, etc, etc.
--dave (Bell labs had a DPS-8 C compiler many moons ago) c-b
--
David Collier-Brown. |{yunexus,utgpu}!geac!lethe!dave
78 Hillcrest Ave,. | He's so smart he's dumb.
Willowdale, Ontario. | --Joyce C-B
Yes, *all* of 'em.
(At least, all of the "50 Series" proprietary processors.)
--
Roger B.A. Klorese MIPS Computer Systems, Inc.
{ames,decwrl,prls,pyramid}!mips!rogerk 25 Burlington Mall Rd, Suite 300
rog...@mips.COM (rogerk%mips...@ames.arc.nasa.gov) Burlington, MA 01803
I don't think we're in toto any more, Kansas... +1 617 270-0613
But why should it abort? If the address is sr:0, (sr = segment register)
subtract 1 to get (sr-1):ffff [or whatever number of 'f's]. Memory
protection, it seems to me, should not notice attempts to compute addresses
but only attempts to access forbidden addresses.
Of course, this approach levies heavy penalities on segmented architecutres.
If you are using the 'small' model (in the 8088 meaning of the word),
sr:0 - 1 = sr:ffff. Now you got to worry about the model. But doesn't the
philosophy of C say 'programmer knows best'. If you want to diddle with
segmented architectures, you got to put up with headaches.
So what am I missing?
-Nath
v...@osupyr.mast.ohio-state.edu
A mathematician is one who starts counting at 0 :-)
Historically, people were suspicious of 'nothing' which is why 0 was not
a number by itself (as opposed to being used in place value notation) till
about 6th century A.D.
As far as indexing goes where one starts makes a difference in terms of
typography :-) More seriously, one may have several things to be indexed,
over a big range (-infinity to infinity even) and each thing is indexed
over some subrange not starting at 0. Changing every origin to 0 is
painful and likely to lead to bugs. Ideally this must be fixed up at the
preprocessor level than at code level. Anybody want to write these
macros?
-Nath
v...@osupyr.mast.ohio-state.edu
Regrettably, some architectures prohibit this: (sr-1):ffff may
mean <undefined segment>:ffff, and the loading of the selector into an
selector register will cause a fault. The basic idea here is that
the operating system pre-fetches a page or segment on being informed
that the program is "about" to need it, as indicated by loading its
selector into a distinguished register.
This behavior is possible on the Honeywell DPS-6[1], and certainly
on an Intel machine running a non-DOS operating system.
--dave (@lethe) c-b
[1] I think the compiler writers watch out for this happening, but
I do know that it makes compiler- & debugger-writing **difficult**.
Anyone from SDG want to comment?
--
David Collier-Brown. | yunexus!lethe!dave
.I have used an Hewlett-Packard HP9000 model 500, which has a very
.strange memory architecture (uses non-contiguous memory
.segments), and a real stack (which means that uninitialized local variables
.contain a zero). Emacs cannot run on it.
^^^^^^^^^^^^^^^^^^^^^^^
Nonsense, many people use Emacs on HP9000/500.
--
Dave Caswell
Greenwich Capital Markets uunet!philabs!gcm!dc
There exist machines whose protection philosophy is to prevent you from
even thinking something illegal. In particular, on the Unisys A-series,
the compiler must implement all memory addressing protection--there is
no kernel/user state protection on memory.* A program cannot be allowed
to form an invalid address, as there is nothing to stop it from using it,
and nothing in the hardware to stop you from stomping on another user
if you do. Therefore, the compiler and the operating system would be
written so as to cause an interrupt if computing 'b - 1' were attempted.
The ANSI rules were written to allow C to be implemented on such an
architecture.
Note that there is no C compiler for the A-series today, although one is
rumored. The rumors say that arrays and pointers will not be implemented
this way, however. In order to get around some other problems, and to allow
more old programs to run, a linear-address space machine will be simulated,
using a large array. (Arrays are hardware concepts on the A-series.)
>Of course, this approach levies heavy penalities on segmented architecutres.
On some architectures, it may be an infinite penalty--C could not be
implemented. Or maybe only by simulating a more PDP-11-like machine
(as discussed above).
>If you are using the 'small' model (in the 8088 meaning of the word),
>sr:0 - 1 = sr:ffff. Now you got to worry about the model. But doesn't the
>philosophy of C say 'programmer knows best'. If you want to diddle with
>segmented architectures, you got to put up with headaches.
You sometimes have to, in order to get some benefits (like having your
OS written in a really high-level language, with no assembler, etc.)
>So what am I missing?
A broad education in the corners of the computer architecture world.
>-Nath
>v...@osupyr.mast.ohio-state.edu
* Note that putting the protection in the compiler was also an idea
of Per Brinch-Hansen's in the 1970s, with Concurrent Pascal. Burroughs
had been doing it for many years, even then.
--
Craig Jackson
UUCP: {harvard!axiom,linus!axiom,ll-xn}!drilex!dricej
BIX: cjackson
A quote from the file etc/MACHINES of the GNU 18.50 distribution:
"The [HP9000] series 500 has a seriously incompatible memory architecture
"which relocates data in memory during execution of a program,
"and support for it would be difficult to implement.
Of course, "other" emacses are available for HP9000 model 500
(MicroEmacs, Jove, Scame, Unipress??).
--
Johan
I believe he is probably referring to GNU Emacs which definitely does
not run on the HP9000/500. There are even references to this fact in
the installation/porting documentation.
About a 15 months ago I ordered Emacs from Unipress software as they said
an HP9000/500 version was available. `Available' meant that they sent out
a source tape with some comments for the HP9000/500. I spent several days
to get to a running version but it was so buggy that everything was boxed
up and returned within the week. Maybe they have it working now...
--
Steve Fullerton Statware, Inc.
scf%statwa...@cs.orst.edu 260 SW Madison Ave, Suite 109
orstcs!statware!scf Corvallis, OR 97333
503/753-5382
In article <8...@osupyr.mast.ohio-state.edu> v...@osupyr.mast.ohio-state.edu
(Vidhyanath K. Rao) asks:
>But why should it abort? If the address is sr:0, (sr = segment register)
>subtract 1 to get (sr-1):ffff [or whatever number of 'f's].
On many machines, addresses are unsigned numbers. The domain and range
of an unsigned 16-bit number is 0..65535. What is the (mathematical)
result of 0 - 1? Answer: -1. Is it in range? No. So what happens?
Integer underflow, which on many machines is a trap.
You can even do this on a VAX, although there you must first enable the
trap (use bispsw or set the appropriate flag in the subroutine entry
mask), and then it only fires on integer computations outside the range
-2 147 483 648..2 147 483 647; so if (for instance) you were to write
main()
{
char *p;
p = (char *)0x7fffffff;
asm("bispsw $0x20"); /* PSL_IV */
p++;
}
This program, when run, aborts with a `floating exception' (SIGFPE).
It would be legal for the C compiler to set IV in the entry point
of each subroutine, although it would probably break too much code
that expects integer overflow/underflow to be ignored, and the code
that does C's `unsigned' arithmetic would have to turn it off temporarily.
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain: ch...@mimsy.umd.edu Path: uunet!mimsy!chris
I am told that the original Fortran/Pascal version is a good book, but
they clearly could have used some help with this version. I
appreciate that they tried to explain and point out the problems of
numerical programming in C, but they often criticize or make uncalled
for assumptions about C due to their ignorance.
For example, the following is a quote from a recent issue of
Micro/Systems Journal which reviewed the book:
They suggest not using switch-case-default construction, ...
because they consider the structure confusing, and also "burdened
by uncertainty, from compiler to compiler about what data types
are allowed in its control expression." It is recommended that
this be replaced by "a more recognizable and translatable if-else
construction."
They [NRC] go on to make many other unfounded remarks, such as "avoid
continue;". Isn't there a better book for numerical programming in C?
Don Libes cme-durer.arpa ...!uunet!cme-durer!libes
What's to stop you from doing the following:
Generate code in an array.
Jump to the beginning of the array. *
Now you've blown the protection. You can do anything. I hope this isn't a
multiuser machine...
* this may involve such things as passing a pointer to an array to a
function that's declared that argument as a pointer to a function, or
even by writing the array out as a file and executing it... I can't see
how you could write a valid 'C' compiler that wouldn't let you violate
this protection.
--
Peter da Silva `-_-' Ferranti International Controls Corporation.
"Have you hugged U your wolf today?" pe...@ficc.uu.net
But nobody says you have to load the selector into a selector register
just to compute an address. Why should the address calculation hardware
be involved at all?
What are the implications of this "relocation of data in memory during
execution" and why would it cause Emacs problems but not problems in
general with C programs which use pointers. (If the HP9000 will move a
block of memory after a pointer to it has been loaded, then the pointer is
now no good... or is it?)
--
|------------Dan Levy------------| THE OPINIONS EXPRESSED HEREIN ARE MINE ONLY
| Bell Labs Area 61 (R.I.P., TTY)| AND ARE NOT TO BE IMPUTED TO AT&T.
| Skokie, Illinois |
|-----Path: att!ttbcad!levy-----|
I may not be the first one to cast a stone at this example, but have
you considered the possibility that a floating point exception is
manifestly the \fBwrong\fP thing to do in your example? There is no
floating-point math in there. Complain to your vendor.
--
...!bikini.cis.ufl.edu!ki4pv!cdis-1!tanner ...!bpa!cdin-1!cdis-1!tanner
or... {allegra killer gatech!uflorida decvax!ucf-cs}!ki4pv!cdis-1!tanner
The version of Gosling Emacs we have is datad 1985.
In article <14...@ficc.uu.net> pe...@ficc.uu.net (Peter da Silva) writes:
-What's to stop you from doing the following:
-
- Generate code in an array.
- Jump to the beginning of the array. *
Whenever the compiler is forced to generate `iffy' code, it also generates
tests such as tags to make sure that you do not do something like this.
The FORTRAN origins of the NRC code are at points quite clear, there
are several routines that could easily have been coded base 0, and
were coded base 1, and so on. The introductory chapter contains
several remarks about C that to the experienced C programmer, and even
to me, sound rather inane. All true.
However, I do not know of any book, in *any* language, that contains
the quality and quantity of numerical material that NRC has. You
should take into account that good numerical analysis is more than 80%
math, so even if the programming job were botched (and it isn't), the
book would be worth its money. Further, apart from the base-0/base-1
array issue that has been beaten to death in this group already, the
actual C code (as opposed to their philosophy about it) is good. The
reason for this is simply that while numerical code may have very
intricate analysis behind it, the actual code tends to be rather
simple -- a couple of for loops and a handful of if's is typical.
Finally, the problem with the base-1 arrays can simply be solved by a
minor change to the vector(), dvector(), ivector(), matrix(),
dmatrix() and imatrix() code, with a corresponding change in the
free_<vector, etc> routines. I posted the change for vector() a while
ago.
In summary, anyone who claims the book to be of little or no value is
not doing it justice.
Rob Carriere
(This is from memory)
When I worked at the Eindhoven University of Technology we had 4 HP9000/500s
and we ported emacs to it.
The real problem (with emacs 16.??) we had was that emacs assumed that a machine
with 32 bit words uses only 24 address bits. The upper 8 were assumed to be free
and available for type tags. In essence, it assumed that all machines have a VAX
like addressing scheme. The HP9000/500 uses all 32 bits. This same problem
occurred every time we tried to port a program which made any assumption on the
format of a pointer.
The "problem" is that the HP9000/500 has a segmented memory architecture. Each
pointer consists of a segment number and a segment offset and then some. At load
time the segments are assigned to the program and each pointer (identified as
such in the load file) is fixed up with the segment number of its associated data.
When you have emacs dump itself to create a faster loadable binary, you would
have to write every pointer back with no segment assigned. For arbitrary pointers
this is a hell of a job.
A colleague of mine succeeded in porting it but without the dump facility. If
you are interrested, you can contact him at the following address:
Geert Leon Janssen
Eindhoven University of Technology,
Department of Electrical Engineering,
P.O. Box 513,
5600 MB Eindhoven, The Netherlands.
(UUCP: ...!mcvax!euteal!geert)
--
Hans Zuidam E-Mail: ha...@nlgvax.UUCP
Philips Telecommunications and Data Systems, Tel: +31 40 892288
Project Centre Geldrop, Building XR
Willem Alexanderlaan 7B, 5664 AN Geldrop The Netherlands
That's simple. All the compiler has to do is detect any attempt to
use a data object as a function. The only way to even attempt this in
standard C is via an explicit cast to a function pointer somewhere,
which is where the compiler would enforce the constraint.
As I remember ... an pointer on the HP9000/500 system is
something you cannot treat as an numeric quantity. Of course, you
should not do that anyway.
I recall the following symptoms:
- address space is not contiguous from zero to somewhere,
pointers contain segment numbers and offsets;
- you cannot store a pointer on disk, and read it back in
another run, because your program will probably not be loaded
in the same memory segments;
- you cannot use the highest bits of a pointer for other
purposes (as GNU Emacs does). All 32 bits contain information.
When you use pointers thru C (e.g. "ptr1 - ptr2" or "ptr[index]")
everything goes well, that's why "normal" applications are not
affected.
Another feature of the HP9000/500 is that local variables are
garanteed to contain 0 (zero) at startup.
--
Johan
In article <70...@cdis-1.uucp> tan...@cdis-1.uucp (Dr. T. Andrews) writes:
>I may not be the first one to cast a stone at this example, but have
>you considered the possibility that a floating point exception is
>manifestly the \fBwrong\fP thing to do in your example? There is no
>floating-point math in there. Complain to your vendor.
What would you have it called? Here are the possible signals:
#define SIGHUP 1 /* hangup */
#define SIGINT 2 /* interrupt */
#define SIGQUIT 3 /* quit */
#define SIGILL 4 /* illegal instruction (not reset when caught) */
#define SIGTRAP 5 /* trace trap (not reset when caught) */
#define SIGIOT 6 /* IOT instruction */
#define SIGABRT SIGIOT /* compatibility */
#define SIGEMT 7 /* EMT instruction */
#define SIGFPE 8 /* floating point exception */
#define SIGKILL 9 /* kill (cannot be caught or ignored) */
#define SIGBUS 10 /* bus error */
#define SIGSEGV 11 /* segmentation violation */
#define SIGSYS 12 /* bad argument to system call */
#define SIGPIPE 13 /* write on a pipe with no one to read it */
#define SIGALRM 14 /* alarm clock */
#define SIGTERM 15 /* software termination signal from kill */
#define SIGURG 16 /* urgent condition on IO channel */
#define SIGSTOP 17 /* sendable stop signal not from tty */
#define SIGTSTP 18 /* stop signal from tty */
#define SIGCONT 19 /* continue a stopped process */
#define SIGCHLD 20 /* to parent on child stop or exit */
#define SIGCLD SIGCHLD /* compatibility */
#define SIGTTIN 21 /* to readers pgrp upon background tty read */
#define SIGTTOU 22 /* like TTIN for output if (tp->t_local<OSTOP) */
#define SIGIO 23 /* input/output possible signal */
#define SIGXCPU 24 /* exceeded CPU time limit */
#define SIGXFSZ 25 /* exceeded file size limit */
#define SIGVTALRM 26 /* virtual time alarm */
#define SIGPROF 27 /* profiling time alarm */
#define SIGWINCH 28 /* window size changes */
#define SIGUSR1 30 /* user defined signal 1 */
#define SIGUSR2 31 /* user defined signal 2 */
You have to squeeze it in somewhere, and in fact the VAX hardware
reports integer overflow and floating exceptions with the same trap /
fault (`arithmetic exception').
> In article <14...@ficc.uu.net> pe...@ficc.uu.net (Peter da Silva) writes:
> -What's to stop you from doing the following:
> -
> - Generate code in an array.
> - Jump to the beginning of the array. *
Chris Torek noted:
> Whenever the compiler is forced to generate `iffy' code, it also generates
> tests such as tags to make sure that you do not do something like this.
So what's to stop me from writing out a load module and subverting
the protection mechanism, as I noted in my (deleted) footnote? I would
think that the perversions necessary to make 'C' safe to run on this machine
would make it sufficiently useless that a little thing like calculating
a pointer to a position before the beginning of an array is a minor
detail...
That is to say, yes... this construct is non-portable. But only to machines
you would have severe problems porting to in the first place.
In article <14...@ficc.uu.net> pe...@ficc.uu.net (Peter da Silva) writes:
>So what's to stop me from writing out a load module and subverting
>the protection mechanism, as I noted in my (deleted) footnote?
The O/S, of course, which cooperates with the compiler as to these tags
or region markers or whatever. In fact, the only way to subvert the
system, if the system is done right, is to take it apart and either
rewire it, or move its disks to another machine and rewrite them, or
something along those lines---i.e., something software is physically
unable to protect against. (I thought this whole line of reasoning was
obvious. [proof by intimidation :-) ])
>I would think that the perversions necessary to make 'C' safe to run
>on this machine would make it sufficiently useless ...
Probably.
Decent memory protection. (There are those of us who believe that
executable and writable memory should be mutually exclusive. (with a
provision to change from one to the other.))
>So what's to stop me from writing out a load module and subverting
>the protection mechanism, as I noted in my (deleted) footnote?
The same type of protection mechinism that makes it impossible
(or hopefully at least difficult) to alter other users files.
Writing out executalbe files may be considered a priviliged
function reserved to compilers.
(Please note I am not saying that I think that compilers are the proper
place to enforce system security, just that portably written code shouldn't
have undue hardship running on such a machine.)
--
Bob Larson Arpa: Bla...@Ecla.Usc.Edu bla...@skat.usc.edu
Uucp: {sdcrdcf,cit-vax}!oberon!skat!blarson
Prime mailing list: info-prime-request%ai...@ecla.usc.edu
oberon!ais1!info-prime-request
Two things stop this:
1. There's no way to 'say it'; see below.
2. There is a tag field on each word of memory. Data has a tag of 0 or 2;
code has a tag of 3. It is the responsibility of the compiler to make sure
that a user program cannot set its own tags. Only the operator can turn
a program into a compiler, and only a compiler can create an object program.
(There are, of course, holes for people with super-user-like privileges.
Just like Unix.)
>* this may involve such things as passing a pointer to an array to a
>function that's declared that argument as a pointer to a function, or
>even by writing the array out as a file and executing it... I can't see
>how you could write a valid 'C' compiler that wouldn't let you violate
>this protection.
Another feature of this system is a type-checking linker. All functions
must agree in number of arguments and type of arguments with their calls.
The linker, called the binder on the A-series, enforces this. (This makes
varargs be a pain in the behind, BTW. One reason why A-series C most likely
will not fully use the hardware, and therefore be a slow, undesirable
language. Much like their PL/I.)
>Peter da Silva `-_-' Ferranti International Controls Corporation.
-Sho
So what's wrong with "many people use Emacs on HP9000/500"? Nobody
(until your posting) said anything about specifically GNU emacs.
der Mouse
old: mcgill-vision!mouse
new: mo...@larry.mcrcim.mcgill.edu
actually sounds a lot like working on an intel iapx86 microprocessor, doesn't it? the restrictions are much the same.
jim nutt
'the computer handyman'
--
St. Joseph's Hospital/Medical Center - Usenet <=> FidoNet Gateway
Uucp: ...ncar!noao!asuvax!stjhmc!15.11!jim.nutt
I'm getting real tired of the "I wanna do X" comments. First,
there is almost (but now always) a better, standard way to do the
same thing. And second, there seems to be a *major*
misunderstanding of what ANSI says.
ANSI does *not* say that you can't jump into your data. All that
it says that this is not guaranteed to work. In other words,
it's nonportable. OF COURSE its nonportable. It's just not
going to work on a machine with a different processor, and it may
not work with a different operating system or a different
compiler.
A similar comment applies to a lot of things that people are
complaining about. ANSI rarely says that, at run time, certain
things are not allowed. Instead, it says things like "if you do
X, the results are undefined (or implementation dependent)".
So you *can* write your incremental compiler and have it conform
to ANSI C (though it will not be maximally conforming). You just
can't do that and assume that it will port. And that is what you
would expect.
Let me make that clear: unless the ANSI standard says that the
compiler *must* prohibit something, that thing is *allowed*. If
there is something reasonable to do on your particular system, so
long as doing it doesn't conflict with the do's and don'ts that
are stated in the standard, the compiler can do it. And you can
use that feature to your hearts content, and have a conforming
program. The program won't be maximally conforming, so it won't
necessarily port easily, but that is the cost of using a system
specific feature.
---
Bill
novavax!proxftl!bill