fwy@ecsvax.UUCP (12/19/84)
Who knows of a FORTRAN - C converter? I have info on one called FORTRIX-C. Has anyone used it? Is it any good? Are there any others? I have 30,000 lines of code to convert over the next two years. Should I be doing this by hand? Will a converter produce good enough code to be worth the price (FORTRIX-C is $2000)? Thankxxx
dgary@ecsvax.UUCP (D Gary Grady) (12/19/84)
<>
There is a real problem in converting FORTRAN to C, because there is one
FORTRAN feature that is widely used and not duplicated in C: the
ability to pass varying-sized arrays as parameters. That is, the
following is not legal C, but the equivalent is legal FORTRAN:
C: FORTRAN:
subr(array, size) SUBROUTINE SUBR(ARRAY,ISIZE)
int size; INTEGER ISIZE
float array[size][]; REAL ARRAY(1,ISIZE)
{ ... ...
} RETURN
END
(I don't believe C formally specifies the order of array elements, but
in practice the row-major form is used, I think. FORTRAN, of course,
stores column-major.)
It is possible to pass variant-sized arrays in C by passing an array of
pointers to arrays, or by simulating a 2-dimensional array by means of a
one-dimensional one (handling the subscript computation with a #define
or a subroutine would be easiest here). But I would like to see this
simple feature added to C; I doubt it would break any existing programs.
D Gary Grady, Duke University Computation Center (dgary@ecsvax)
{...!(ihnp4,decvax,etc)!mcnc!ecsvax!dgary}
--
D Gary Grady
Duke University Computation Center, Durham, NC 27706
(919) 684-4146
USENET: {decvax,ihnp4,akgua,etc.}!mcnc!ecsvax!dgary
david@ukma.UUCP (David Herron, NPR Lover) (12/27/84)
[ I don't write until I supply stuff I am talking about ... ] > From: dgary@ecsvax.UUCP (D Gary Grady) > Newsgroups: net.lang.c,net.lang.f77 > Subject: Re: Converting FORTRAN to C > Message-ID: <396@ecsvax.UUCP> > Date: Wed, 19-Dec-84 10:13:26 EST > <> > There is a real problem in converting FORTRAN to C, because there is one > FORTRAN feature that is widely used and not duplicated in C: the > ability to pass varying-sized arrays as parameters. That is, the > following is not legal C, but the equivalent is legal FORTRAN: Does C not allow this? Gee, what about that BASIC interpretor I wrote a year ago that used arrays of int (varying size) to store the intermediate code? These arrays got passed to most of the routines in the interpretor. My code worked too. > C: FORTRAN: > subr(array, size) SUBROUTINE SUBR(ARRAY,ISIZE) > int size; INTEGER ISIZE > float array[size][]; REAL ARRAY(1,ISIZE) > { ... ... > } RETURN > END > (I don't believe C formally specifies the order of array elements, but > in practice the row-major form is used, I think. FORTRAN, of course, > stores column-major.) There ARE a number of implied pushes to this storage format. I just checked the proposed standard on this. No specific mention (that I could find) was made, BUT.... There was a discussion on initializers. A pertinent example from the text is: float y[4][3] = { { 1, 3, 5 }, { 2, 4, 6 }, { 3, 5, 7 }, }; is a definition with a completely bracketed initialization: 1, 3, and 5 initialize the first row of the array object y[0], namely y[0][0], y[0][1], and y[0][2]. Likewise the next two lines initialize y[1] and y[2]. The initializer ends earli, so y[3] is initialized with 0's. [page 41, edition as of October 17, 1984] Which certainly isn't proof, but at least implication of proof. Proof is of the form of a long winded preaching on C. You will remember that an array is nothing more than "const int *x", where x points at a block of memory that is the array. The notation of "int x[3]" => "const int *x" is extended recursively for arrays with more dimensions. ("int x[3][5]" => "const int *x[3]"). Meaning that a two dimensioned array is actually a one dimensioned array of int *'s to one dimensioned arrays of ints. This builds as you build deeper levels of indexing. My contention is that this *forces* row-order storage of arrays, (at least in the old notion of arrays). This actually is a qualitatively different way of thinking about arrays that isn't quite compatible with older ways of thought. > It is possible to pass variant-sized arrays in C by passing an array of > pointers to arrays, or by simulating a 2-dimensional array by means of a > one-dimensional one (handling the subscript computation with a #define > or a subroutine would be easiest here). But I would like to see this > simple feature added to C; I doubt it would break any existing programs. Why is this important? The compiler doesn't need to know how big arrays are, it has a pointer to its base and the size of each element. Only if the compiler is doing code for range bounds checking would that be important. Otherwise the code can be written to check array bounds by hand. (allowing for more efficient bounds checking. Rather than it being done for each reference it only has to be done for *unsure* references.) You are already passing in the size of the array..... so your calling program doesn't change. Break existing programs? Any program that is referencing outside the bounds of an array is already broken, and should be shot on sight. :-) (unless it can give good reason for behaving in such a manner). > D Gary Grady, Duke University Computation Center (dgary@ecsvax) > {...!(ihnp4,decvax,etc)!mcnc!ecsvax!dgary} > -- > D Gary Grady > Duke University Computation Center, Durham, NC 27706 > (919) 684-4146 > USENET: {decvax,ihnp4,akgua,etc.}!mcnc!ecsvax!dgary [why do people sign things twice?] --:--:--:--:--:--:--:--:--:--:--:--:--:--:--:--:--:--:--:--:--:--:--:--:- David Herron; ARPA-> "ukma!david"@ANL-MCS (Try the arpa address w/ and w/o the quotes, I have had much trouble with both.) UUCP -:--:--:--:--:--:--:--:--:- (follow one of these routes) {ucbvax,unmvax,boulder,research} ! {anlams,anl-mcs} -----\ vvvvvvvvvvv >-!ukma!david {cbosgd!hasmed,mcvax!qtlon,vax135,mddc} ! qusavx -----/ ^^^^^^^^^^^
john@physiol.OZ (John Mackin) (12/30/84)
In article <435@ukma.UUCP>, david@ukma.UUCP (David Herron, NPR Lover) writes: > Any program that is referencing outside > the bounds of an array is already broken, and should be shot on > sight. :-) (unless it can give good reason for behaving in such a manner). There is at least one excellent reason, commonly used in C, for referencing beyond the bounds of an array. It is this: #define ARRAYSIZE 200 type_t array[ARRAYSIZE]; ... type_t *p; for (p = array; p < &array[ARRAYSIZE]; p++) ... Now, sure you could say "p <= &array[ARRARYSIZE - 1]" instead. But which is clearer, and easier to read ... and, more importantly, used in many, many places in V7 UNIX as distributed by AT&T? I get VERY ANGRY at compilers like Whitesmiths' (for VAX/VMS, at least) that get upset about this construct. After all, this is C, not PASCAL or some other wimp's language that checks array bounds. :-) John Mackin, Physiology Department, University of Sydney, Sydney, Australia ...!decvax!mulga!physiol.su.oz!john
dgary@ecsvax.UUCP (01/02/85)
David Herron's posting prompts me to clarify and correct my comments on C's lack of the valuable ability to pass varying sized arrays of two or more dimensions. To recap briefly, FORTRAN and a few other languages allow the passing of arrays to subroutines without the subroutine "knowing" in advance the size of the array. This is true in C only for one-dimensional arrays, or multi-dimensional "arrays" set up as a chain of arrays of pointers to arrays. David repeats a common misconception when he says: > ... Meaning > that a two dimensioned array is actually a one dimensioned array of > int *'s to one dimensioned arrays of ints. This builds as you build > deeper levels of indexing. It is, of course, possible to create such an "array" in C, but an array declared, say, "float array[20][30]" is NOT set up as an array of pointers to an array of floats; it is all in contiguous storage, and C does a routine subscript calculation to determine the offset (see K&R, for example). In a sense, this is a case of ambiguity in the C notation array[][]; the compiler has to know the kind of animal it's dealing with. In practice, of course, this information is readily available from the symbol table, and I can't think of too many cases where the exact semantics would be important to the programmer. Perhaps a notation of array[i;j] would be useful for two-dimensional arrays of the conventional (i.e., continguous storage) variety. Anyway, David goes on to quote me: >> It is possible to pass variant-sized arrays in C by passing an array of >> pointers to arrays, or by simulating a 2-dimensional array by means of a >> one-dimensional one (handling the subscript computation with a #define >> or a subroutine would be easiest here). But I would like to see this >> simple feature added to C; I doubt it would break any existing programs. > >Why is this important? The compiler doesn't need to know how big arrays >are ... ? > > David Herron; ARPA-> "ukma!david"@ANL-MCS > (Try the arpa address w/ and w/o the quotes, I have had much trouble with both.) > > UUCP -:--:--:--:--:--:--:--:--:- (follow one of these routes) > >{ucbvax,unmvax,boulder,research} ! {anlams,anl-mcs} -----\ vvvvvvvvvvv > >-!ukma!david > {cbosgd!hasmed,mcvax!qtlon,vax135,mddc} ! qusavx -----/ ^^^^^^^^^^^ The compiler needs to know all but the last dimension size to compute the offset. By the way, I was incorrect when I said that C did not specify row-major storage; it does, in fact, and David's description of why is accurate and succinct. -- D Gary Grady Duke University Computation Center, Durham, NC 27706 (919) 684-4146 USENET: {decvax,ihnp4,akgua,etc.}!mcnc!ecsvax!dgary
ndiamond@watdaisy.UUCP (Norman Diamond) (01/02/85)
> There is at least one excellent reason, commonly used in C, for referencing > beyond the bounds of an array. It is this: > > #define ARRAYSIZE 200 > > type_t array[ARRAYSIZE]; > > ... > > type_t *p; > > for (p = array; p < &array[ARRAYSIZE]; p++) > ... &array[ARRAYSIZE] does not reference any part of the array. However, after the loop is exited due to the stated condition, if code dereferences p (i.e. uses *p), THEN the code is referencing beyond the array bounds and is broken and should not be of concern to language translators. -- Norman Diamond UUCP: {decvax|utzoo|ihnp4|allegra|clyde}!watmath!watdaisy!ndiamond CSNET: ndiamond%watdaisy@waterloo.csnet ARPA: ndiamond%watdaisy%waterloo.csnet@csnet-relay.arpa "Opinions are those of the keyboard, and do not reflect on me or higher-ups."
ndiamond@watdaisy.UUCP (Norman Diamond) (01/02/85)
> type_t array[ARRAYSIZE]; > ... > type_t *p; > for (p = array; p < &array[ARRAYSIZE]; p++) > I get VERY ANGRY at compilers like Whitesmiths' (for VAX/VMS, at least) that > get upset about this construct. In that case, it sounds like Whitesmiths' compiler is broken. Incidentally, Pascal doesn't have an address-of operator (&), so a comparison to Pascal cannot be made. Also, I haven't seen a Pascal compiler that forced bounds checking on users whether they wanted it or not -- though I could imagine that a tool for teaching first-year students would do so. However, anyone who criticizes the availability of such debugging tools (wimpish, etc.) should be denied access to all debugging tools other than post-mortem dumps printed in hex (or octal) on a line printer. Sure, I've read OS dumps too, but debugging takes an order of magnitude longer. -- Norman Diamond UUCP: {decvax|utzoo|ihnp4|allegra|clyde}!watmath!watdaisy!ndiamond CSNET: ndiamond%watdaisy@waterloo.csnet ARPA: ndiamond%watdaisy%waterloo.csnet@csnet-relay.arpa "Opinions are those of the keyboard, and do not reflect on me or higher-ups."
dave@lsuc.UUCP (David Sherman) (01/02/85)
In article <103@physiol.OZ> john@physiol.OZ (John Mackin) writes: || There is at least one excellent reason, commonly used in C, for referencing || beyond the bounds of an array. It is this: || || for (p = array; p < &array[ARRAYSIZE]; p++) Hmm. I'd MUCH rather say for(p = array; p - array < ARRAYSIZE; p++) which doesn't break any compiler. But your point is well taken; your example shouldn't be grounds for compiler indigestion. Dave Sherman -- {utzoo pesnta nrcaero utcs}!lsuc!dave {allegra decvax ihnp4 linus}!utcsrgv!lsuc!dave
bsa@ncoast.UUCP (Brandon Allbery (the tame hacker on the North Coast)) (01/04/85)
Having just yesterday sent a response to a message denying that Cuses
contiguous storage, I find myself with egg on my face, having been bitten
by that feature of C that I love to hate: the fact that the apparent
and real semantics of array declarations are wildly at variance with
each other. The C compiler goes to great lengths to make
int a[5][2];
look like
a ----> (a1) (a2) (a3) (a4) (a5)
| | | | |
V V V V V
(a1.1) (a2.1) (a3.1) (a4.1) (a5.1)
(a1.2) (a2.2) (a3.2) (a4.2) (a5.2)
...but `a' is really a constant and a1, a2, a3, a4, a5 have no objective
existance at all. This really galls me; why make it look like something
it cannot be? The pointer model takes up more memory, but has quite
a few advantages over the block data (forgive me, ForTran-ers! :-) model.
I would prefer that, consistent with the rest of the pointer/array equi-
valency, array[][] were REALLY equivalent to **array. The latter is
used more often (strings) anyway.
It's too late to save C. I'm still working on a C-like language which
uses my idea of pointers/arrays. (Unfortuantely, our lex has shown a
regrettable tendency to core-dump for no reason at all, and generated
programs (if it doesn't coredump) also usually dump core.)
--bsa
--
Brandon Allbery @ decvax!cwruecmp!ncoast!bsa (..ncoast!tdi1!bsa business)
6504 Chestnut Road, Independence, Ohio 44131 (216) 524-1416
Who said you had to be (a) a poor programmer or (b) a security hazard
to be a hacker?
chris@umcp-cs.UUCP (Chris Torek) (01/04/85)
The real trick to doing ``bounds checking'' in C is in figuring out exactly what ``bounds'' really means. Is ``p[-1]'' out of bounds? Maybe, maybe not. How about *(p - 1)? It's the same thing. p-1 is certainly not out of bounds. &foo[bar] can never be (I claim). How about this code fragment: f() { register char *p; char *g(); p = g(10); p[-4] = 0; } Is p[-4] out of bounds? Depends on what g(10) returns! (Ouch.) If you really try hard, you could come up with runtime checks that really worked, by having every library function and every compile time array and every block of storage have an associated descriptor, with rules for combining blocks and so forth. Trouble is, you'd wind up with something almost the same as this: if ((addr & 0x8000000) == 0) { if ((addr & 0x40000000) == 0) { if (addr < P0BR || addr > P0BR + P0LR) ... } else { if (addr < P1BR || addr > P1BR + P1LR) ... } } else { if (addr < SBR || addr > SBR + SLR) ... } Look familiar? Hm... you could even use ``segmentation fault'' and ``bus error'' to distinguish the two major cases.... :-) -- (This line accidently left nonblank.) In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (301) 454-7690 UUCP: {seismo,allegra,brl-bmd}!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@maryland
david@ukma.UUCP (David Herron, NPR Lover) (01/06/85)
In article <103@physiol.OZ>, john@physiol.OZ (John Mackin) writes: >In article <435@ukma.UUCP>, david@ukma.UUCP (David Herron, NPR Lover) writes: >> Any program that is referencing outside >> the bounds of an array is already broken, and should be shot on >> sight. :-) (unless it can give good reason for behaving in such a manner). >Now, sure you could say "p <= &array[ARRARYSIZE - 1]" instead. But which >is clearer, and easier to read ... and, more importantly, used in many, >many places in V7 UNIX as distributed by AT&T? I get VERY ANGRY at compilers >like Whitesmiths' (for VAX/VMS, at least) that get upset about this construct. >After all, this is C, not PASCAL or some other wimp's language that >checks array bounds. :-) Aaaaahhhhhhh, but your code is not a *real* reference. It is simply a calculation of an address, and knowledge that for this array, a certain address is a good trailer value. I of course meant in my posting that any program that WRITES outside an array is already broken. (I know, I know, there are times when even that can be useful, such as the following #define's I wrote for someone with C on an apple. And ya know how them Apple programmers just can't program without putting in poke statements :-) .) #define poke(adr,val) (*((char *)adr)) = ((char)val) #define peek(adr) (*((char *)adr)) And Whitesmith's should be shot for being such a terminally *almost good* compiler.
msb@lsuc.UUCP (Mark Brader) (01/10/85)
> ... that feature of C that I love to hate: ...the apparent > and real semantics of array declarations are wildly at variance with > each other. The C compiler goes to great lengths to make > > int a[5][2]; > > look like > > a ----> (a1) (a2) (a3) (a4) (a5) > | | | | | > V V V V V > (a1.1) (a2.1) (a3.1) (a4.1) (a5.1) > (a1.2) (a2.2) (a3.2) (a4.2) (a5.2) > > ...but `a' is really a constant and a1, a2, a3, a4, a5 have no objective > existence at all. This really galls me; ... Sure they do; they just don't take up any memory. They're pointer-valued constants, just as a is itself. a[2] is a constant, just as if it was declared as int (*a2)[2]; --Why shouldn't it be? Mark Brader
bsa@ncoast.UUCP (Brandon Allbery (the tame hacker on the North Coast)) (01/17/85)
> Article <277@lsuc.UUCP>, from msb@lsuc.UUCP (Mark Brader) +---------------- | Sure they do; they just don't take up any memory. They're pointer-valued | constants, just as a is itself. a[2] is a constant, just as if it was | declared as int (*a2)[2]; --Why shouldn't it be? Because, since they LOOK like independent pointers, programmers may (try to) USE them as independent pointers. And it can confuse related issues, such as the use of "environ". It sure confused ME until I figured out that they lied about [] usage being identical to *. --bsa -- Brandon Allbery @ decvax!cwruecmp!ncoast!bsa (..ncoast!tdi1!bsa business) 6504 Chestnut Road, Independence, Ohio 44131 +1 216 524 1416 (or what have you) Who said you had to be (a) a poor programmer or (b) a security hazard to be a hacker?