[comp.lang.misc] Relationship between C and C++

billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe, 2847 ) (03/19/90)

From peter@ficc.uu.net (Peter da Silva):
> Classic Ada is no more Ada than C++ is C.

  Then perhaps we should ask, "Exactly what IS the relationship
  between C++ and C?"  Let's see what recently-quoted author Bertrand
  Meyer (author of _Object-Oriented Software Construction_) has to say:

...Quoting from Dr. Bjarne Stroustrup's ``The
C++ Programming Language'' (Addison-Wesley, 1986), which seems to be the
major reference on C++, page 22, lines 13-14: ``A C++ program typically
consists of many source files, each containing a sequence of declarations
of types, functions, variables, and constants''. This is very far from the
object-oriented model of software decomposition. 

...One of my major objections to C++ stems from what that language has
rather than what it has not. Because C++ retains almost total
compatibility with C, it keeps all its low-level and dangerous features.
The design of C dates back to the late sixties and is obsolete
by modern software engineering standards.

Compatibility with C means that in C++ you still have pointers,
type casts, pointer arithmetic, function pointers, malloc, free, bizarre
operator precedence (the famous asterisk/parenthesis bugs),
weak type checking and so on.

    I strongly disagree with this approach if the goal is to obtain software
quality. Take pointer arithmetic, for example. I would contend that you can
have quality software, or you can have pointer arithmetic; but you cannot
have both...

-- Bertrand Meyer
bertrand@eiffel.com
4 Jun 89 23:48:27 GMT

woody@eos.UUCP (Wayne Wood) (03/20/90)

In article <8432@hubcap.clemson.edu> billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu writes:
>compatibility with C, it keeps all its low-level and dangerous features.
                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

C is like a loaded gun... it is only dangerous if the person using it does not
know what they are doing.

>
>    I strongly disagree with this approach if the goal is to obtain software
>quality. Take pointer arithmetic, for example. I would contend that you can
>have quality software, or you can have pointer arithmetic; but you cannot
>have both...
>

give me a break!

/***   woody   ****************************************************************
*** ...tongue tied and twisted, just an earth bound misfit, I...            ***
*** -- David Gilmour, Pink Floyd                                            ***
****** woody@eos.arc.nasa.gov *** my opinions, like my mind, are my own ******/

news@awdprime.UUCP (USENET News) (03/20/90)

In article <8432@hubcap.clemson.edu> billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu writes:
-...Let's see what recently-quoted author Bertrand Meyer (...) has to say:
-    ...
-    I strongly disagree with this approach if the goal is to obtain software
-quality. Take pointer arithmetic, for example. I would contend that you can
-have quality software, or you can have pointer arithmetic; but you cannot
-have both...
"Quality Software" is NOT mutually exclusive with "pointer arithmetic"?
I would contend that you can have quality software with pointer
arithmetic, or no software at all.

I would contend that you can write quality software without being a
language bigot, or you can program in a high level language; but not both.
-- sanders                          The 11th commandment: "Thou shalt use lint"
For every message of the day, a new improved message will arise to overcome it.
Reply-To: cs.utexas.edu!ibmaus!auschs!sanders.austin.ibm.com!sanders     (ugh!)

robison@m.cs.uiuc.edu (03/20/90)

>     I strongly disagree with this approach if the goal is to obtain software
> quality. Take pointer arithmetic, for example. I would contend that you can
> have quality software, or you can have pointer arithmetic; but you cannot
> have both...

This is not the first attack on pointer arithmetic that I have seen.
Why is pointer arithmetic denigrated so much?  The C-style pointer
arithmetic seems to me to implement a fairly simple abstraction,
roughly equivalent to ``a tape and a read/write head.''
Most C implementations do not do bounds checking on pointers, 
but I fail to see why pointer arithmetic is inherently evil.

Can anyone clue me as to the basis for pointer paranoia?

Arch D. Robison
University of Illinois at Urbana-Champaign

UUCP: {pur-ee,convex}!uiucdcs!robison
Internet: robison@CS.UIUC.EDU

jdudeck@polyslo.CalPoly.EDU (John R. Dudeck) (03/20/90)

In article <5200048@m.cs.uiuc.edu> robison@m.cs.uiuc.edu writes:
>Why is pointer arithmetic denigrated so much?
>
>Can anyone clue me as to the basis for pointer paranoia?

I look at it as relating to the temperament of the programmer.  Different
people just respond better to different approaches.  It is exactly the
same issue as the debate between the Mac and the PC.  Some like a system
that provides you with a Good Way to do whatever you want to do (i.e.
the Mac and Ada) and others like a system that lets you pick your way
of doing it (i.e. the PC and C).  The first way gets the job done and
doesn't let you make mistakes.  The second way gives you a lot more
flexibility, but you have to learn more and maybe work a little harder
to get it right.

There are many different ways to map a problem onto a computer-based
solution.  Different programming backgrounds lead a programmer to 
find his solution in a different way.

I really think that those who are opposed to C, pointers, and all that
goes with it, are more motivated by a desire to have programming done
by grunt laborers in a DP shop environment, and have better productivity
than has been had in the past with Cobol and Basic.  Those who like
C are more of the craftsman type that like to produce finely wrought
masterpieces.

Of course this is just my point of view...

-- 
John Dudeck                           "You want to read the code closely..." 
jdudeck@Polyslo.CalPoly.Edu             -- C. Staley, in OS course, teaching 
ESL: 62013975 Tel: 805-545-9549          Tanenbaum's MINIX operating system.

drc@cs.brown.edu (David R. Chase) (03/20/90)

In article <5200048@m.cs.uiuc.edu> robison@m.cs.uiuc.edu writes:
>This is not the first attack on pointer arithmetic that I have seen.
>Why is pointer arithmetic denigrated so much?  The C-style pointer
>arithmetic seems to me to implement a fairly simple abstraction,
>roughly equivalent to ``a tape and a read/write head.''
>Most C implementations do not do bounds checking on pointers, 
>but I fail to see why pointer arithmetic is inherently evil.
>
>Can anyone clue me as to the basis for pointer paranoia?

Well, one good reason is that in many cases where it pays to do
pointer arithmetic (loop invariant code, reduction in strength,
redundant expression elimination), the compiler can do (using
algorithms published more than 5 years ago) about as good a job as you
can, except that it won't occasionally make mistakes, and it will
remember to get it right again when the code is modified.

I won't lie to you and tell you that most compilers are this good, but
a good compiler (a really good compiler) might NOT do the pointer
arithmetic because of other constraints (tight for registers, e.g.)
that would cause the code to run slower.  See also the paper by Allen
and Johnson in the 1988 SIGPLAN PLDI -- they describe (among other
things) ripping out the pointer arithmetic to discover where vector
operations would be appropriate.  As dependence analysis is put to
better use on scalar machines (helps scheduling, e.g.), you'll find
that the difficulty in analyzing programs will hurt more.

Now, of course, this doesn't make sense if it costs more to run the
optimizer than it does to pay you to write and maintain that
hand-optimized code, but I really doubt it; it's 1990, not 1950.  You
can't assume that all machines have really good optimizing compilers,
but then you don't see too many people trying to port Gnu emacs to a
6502, either -- just treat it as part of the architecture.

So basically, the reasons to avoid pointer arithmetic are:
1) unnecessary
2) error-prone
3) hindrance to some optimizers

Good enough?

David Chase, Menlo Park, CA

CMH117@psuvm.psu.edu (Charles Hannum) (03/20/90)

In article <6515@eos.UUCP>, woody@eos.UUCP (Wayne Wood) says:
>
>>    I strongly disagree with this approach if the goal is to obtain software
>>quality. Take pointer arithmetic, for example. I would contend that you can
>>have quality software, or you can have pointer arithmetic; but you cannot
>>have both...
>
>give me a break!

B-)  B-)


Virtually,
- Charles Martin Hannum II       "Klein bottle for sale ... inquire within."
    (That's Charles to you!)     "To life immortal!"
  cmh117@psuvm.{bitnet,psu.edu}  "No noozzzz izzz netzzzsnoozzzzz..."
  c9h@psuecl.{bitnet,psu.edu}    "Mem'ry, all alone in the moonlight ..."

sakkinen@tukki.jyu.fi (Markku Sakkinen) (03/20/90)

In article <2605a117.396e@polyslo.CalPoly.EDU> jdudeck@polyslo.CalPoly.EDU (John R. Dudeck) writes:
- ...
-I really think that those who are opposed to C, pointers, and all that
-goes with it, are more motivated by a desire to have programming done
-by grunt laborers in a DP shop environment, and have better productivity
-than has been had in the past with Cobol and Basic.  Those who like
-C are more of the craftsman type that like to produce finely wrought
                                                       ^^^^^^^^^^^^^^
-masterpieces.
 ^^^^^^^^^^^^
-
-Of course this is just my point of view...

I assume you have not had a chance to look at UNIX source code,
for instance ...

Markku Sakkinen
Department of Computer Science
University of Jyvaskyla (a's with umlauts)
Seminaarinkatu 15
SF-40100 Jyvaskyla (umlauts again)
Finland
          SAKKINEN@FINJYU.bitnet (alternative network address)

nick@lfcs.ed.ac.uk (Nick Rothwell) (03/20/90)

In article <2605a117.396e@polyslo.CalPoly.EDU>, jdudeck@polyslo (John R. Dudeck) writes:
>I really think that those who are opposed to C, pointers, and all that
>goes with it, are more motivated by a desire to have programming done
>by grunt laborers in a DP shop environment,

Wrong wrong wrong.

I'm opposed to C, pointers, and all that goes with it, because there
are much better languages in the world for most of the things I
(and other people, I suspect) want to do, and I'm fed up with all
this argument over a brain-dead low-level 20-year-old language.
Give me ML, some other functional language, maybe Scheme, maybe
even Eiffel, Quest, Amber, or whatever, but leave out the C.

>Those who like
>C are more of the craftsman type that like to produce finely wrought
>masterpieces.

Are you serious?

>Of course this is just my point of view...

And this is mine.

>John Dudeck

		Nick.
--
Nick Rothwell,	Laboratory for Foundations of Computer Science, Edinburgh.
		nick@lfcs.ed.ac.uk    <Atlantic Ocean>!mcsun!ukc!lfcs!nick
~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~
      A prop?   ...or wings?      A prop?   ...or wings?      A prop?

nick@lfcs.ed.ac.uk (Nick Rothwell) (03/20/90)

In article <6515@eos.UUCP>, woody@eos (Wayne Wood) writes:
>C is like a loaded gun... it is only dangerous if the person using it does not
>know what they are doing.

Please answer me ONE question:

What is this wonderful "power" which C is giving me, which requires
me to live with all the pitfalls?

		Nick.
--
Nick Rothwell,	Laboratory for Foundations of Computer Science, Edinburgh.
		nick@lfcs.ed.ac.uk    <Atlantic Ocean>!mcsun!ukc!lfcs!nick
~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~
      A prop?   ...or wings?      A prop?   ...or wings?      A prop?

jack@cs.glasgow.ac.uk (Jack Campin) (03/20/90)

robison@m.cs.uiuc.edu wrote:

> Why is pointer arithmetic denigrated so much?  The C-style pointer
> arithmetic seems to me to implement a fairly simple abstraction,
> roughly equivalent to ``a tape and a read/write head.''
> Most C implementations do not do bounds checking on pointers, 
> but I fail to see why pointer arithmetic is inherently evil.

> Can anyone clue me as to the basis for pointer paranoia?

Garbage collection, for one.  If you try to implement a BCPL-family
language on a machine/OS with garbage-collected object memory [i.e. a
storage model a bit more sophisticated than a Turing machine], you have
real problems identifying what objects are still being referenced when
pointers can be incremented.

Secondly, real machines are sufficiently different from the Turing tape
that the result of a pointer arithmetic operation is not merely wordsize-
dependent like normal computer "arithmetic", it's OS-dependent.  Or do C
fans think it's a good idea to have operator semantics vary with the host
segmentation scheme?

Thirdly, the aliasing it enables is a semantic mess.  If anyone claims
different, let's see your denotational model of ANSI C.

-- 
--  Jack Campin   Computing Science Department, Glasgow University, 17 Lilybank
Gardens, Glasgow G12 8QQ, Scotland   041 339 8855 x6044 work  041 556 1878 home
JANET: jack@cs.glasgow.ac.uk    BANG!net: via mcvax and ukc   FAX: 041 330 4913
INTERNET: via nsfnet-relay.ac.uk   BITNET: via UKACRL   UUCP: jack@glasgow.uucp

freek@fwi.uva.nl (Freek Wiedijk) (03/21/90)

In article <2605a117.396e@polyslo.CalPoly.EDU>
jdudeck@polyslo.CalPoly.EDU (John R. Dudeck) writes:
>                                                      Some like a system
>that provides you with a Good Way to do whatever you want to do (i.e.
>the Mac and Ada) and others like a system that lets you pick your way
>of doing it (i.e. the PC and C).

I'm taking offense to your mentioning the Mac and Ada in one sentence.
The Mac is BEAUTIFUL.  Ada is UGLY.  So there!

Freek "the Pistol Major" Wiedijk                  Path: uunet!fwi.uva.nl!freek
#P:+/ = #+/P?*+/ = i<<*+/P?*+/ = +/i<<**P?*+/ = +/(i<<*P?)*+/ = +/+/(i<<*P?)**
--
Freek "the Pistol Major" Wiedijk                  Path: uunet!fwi.uva.nl!freek
#P:+/ = #+/P?*+/ = i<<*+/P?*+/ = +/i<<**P?*+/ = +/(i<<*P?)*+/ = +/+/(i<<*P?)**

plogan@mentor.com (Patrick Logan) (03/21/90)

In article <2605a117.396e@polyslo.CalPoly.EDU> jdudeck@polyslo.CalPoly.EDU (John R. Dudeck) writes:
   I really think that those who are opposed to C, pointers, and all that
   goes with it, are more motivated by a desire to have programming done
   by grunt laborers in a DP shop environment, and have better productivity
   than has been had in the past with Cobol and Basic.  Those who like
   C are more of the craftsman type that like to produce finely wrought
   masterpieces.

You're wrong in at least one instance. My opposition is motivated by a
desire to have programming done by craftsfolk who like to produce
without the hindrance of managing pointers or the storage space they
point to. Let the system manage that level, tempered by a healthy
respect for the capabilities of the system (i.e. don't abuse the
system!).

Of course, yes, of course, for now this is not always possible. But I
would guess that most applications can perform very well in a language
system that manages pointers and storage allocation. That leaves more
time to improve the application itself.

-- 
Patrick Logan  uunet!mntgfx!plogan | 
Mentor Graphics Corporation        | 
Beaverton, Oregon 97005-7191   	   |

preston@titan.rice.edu (Preston Briggs) (03/21/90)

In article <5200048@m.cs.uiuc.edu> robison@m.cs.uiuc.edu writes:

>Can anyone clue me as to the basis for pointer paranoia?

Just because I'm paranoid doesn't mean I'm stoopid.

Let's do some pointer arithmetic.
First we need some declarations:

	typedef struct {
		int i;		/* say 4 bytes */
		char c;
	    } Node, *Nodes;


	Nodes x, y;
	int i, j;

And then some code (assume with me that things are initialized):

	x = y + i;

This means assign the sum of y and i*5.  Not too bad, 1 shift and 3 adds.
Let's do some more:

	j = x - y;

Hmmm.  A subtract and a DIVISION by 5!?

This stuff is great!  Plus costs 4 times what it should and minus
becomes worse than division.  *And* it makes my code obscure to
myself and others, not to mention hard to optimize.  Such a deal.

--
Preston Briggs				looking for the great leap forward
preston@titan.rice.edu

lgm@cbnewsc.ATT.COM (lawrence.g.mayka) (03/21/90)

In article <5200048@m.cs.uiuc.edu> robison@m.cs.uiuc.edu writes:
>Most C implementations do not do bounds checking on pointers, 
>but I fail to see why pointer arithmetic is inherently evil.

My own objection to pointer arithmetic in a purportedly
object-oriented language such as C++ is that pointer arithmetic
assumes that the storage cells actually referenced by the pointer
at run time have the precise size denoted by the pointer's
compile-time declaration.  Thus, if I construct an array of
objects of class Derived (derived from Base), and pass that array
as argument to a function declared to accept a pointer to a Base -
a perfectly legal and automatic coercion - and the function
attempts to index into the array/off the pointer, the result is
random garbage.  If Derived has virtual functions, I might even
overwrite a pointer to its virtual function table.  The next
virtual function call then gives "Memory fault, core dumped." An
attempt to delete the array of Derived through a Base pointer can
cause less debuggable havoc - repeatedly calling the Base
destructor with incorrect pointers - and this is even if one
remembers to specify the size of the array (which the requestor of
the deletion is expected to know, but whose omission is quite
legal and prevents the necessary calling of the destructor on each
array element).

In short, the C array is a poor substitute for an indexable
collection type, and the C pointer is a poor iterator for such a
type.

>Can anyone clue me as to the basis for pointer paranoia?

Programming languages such as Common Lisp and Smalltalk support an
abstraction of storage (memory) itself, in which memory consists
exclusively of typed objects, and those objects are referenced by
names (bindings).  Assignment is essentially a rebinding; physical
copying is a rather unusual operation, performed only when one
specifically wishes to preserve a mutable object's current state
in the face of possible future alteration by others.  Pointers
vitiate this abstraction by encouraging the more primitive view of
memory as merely an enormous array of untyped machine words, to be
used or abused in whatever way the programmer desires.  This loss
of abstraction is particularly acute when pointer casting is
permitted and encouraged, and especially when pointers are often
coerced automatically and silently by the compiler.

Many languages outright encourage a pointer implementation in
which an integer or other datum can have the same bit pattern as a
pointer.  This almost completely rules out truly reliable garbage
collection, further invalidating the objects/bindings abstraction.


	Lawrence G. Mayka
	AT&T Bell Laboratories
	lgm@ihlpf.att.com

Standard disclaimer.

barmar@think.com (Barry Margolin) (03/21/90)

In article <4869@vanuata.cs.glasgow.ac.uk> jack@cs.glasgow.ac.uk (Jack Campin) writes:
>robison@m.cs.uiuc.edu wrote:
>> Can anyone clue me as to the basis for pointer paranoia?
>Garbage collection, for one.  If you try to implement a BCPL-family
>language on a machine/OS with garbage-collected object memory [i.e. a
>storage model a bit more sophisticated than a Turing machine], you have
>real problems identifying what objects are still being referenced when
>pointers can be incremented.

I don't have any such trouble with the C implementation on my Symbolics
Lisp Machine.  On this system, C pointers are implemented as a combination
of an array object reference and an integer byte offset.  Malloc()
allocates such arrays, static variables are implemented as arrays allocated
by the runtime system, and activation records are implemented as arrays
when there are pointers to any of its automatic variables.  When there are
no pointers to the array it becomes garbage.  Pointer arithmetic can never
cause a pointer to jump from one object to another, and attempts to
subtract pointers associated with different objects can often be detected.

On more conventional architectures this could be done using pointer handles
(as in the Mac OS) and an offset.  For efficiency during loops the handle
could be locked, dereferenced, and incremented by the offset; when the loop
is through the offset would be updated and the handle unlocked, at which
time garbage collection can relocate the object and update the handle.

--
Barry Margolin, Thinking Machines Corp.

barmar@think.com
{uunet,harvard}!think!barmar

peter@ficc.uu.net (Peter da Silva) (03/21/90)

> What is this wonderful "power" which C is giving me, which requires
> me to live with all the pitfalls?

There are only two languages I know of in which you can take a moderately
complex program and run it, without modification, on a wide variety of
platforms.

One is Fortran, with the Software Tools library.
The other is C.

Which would you rather use?

How much of this is due to historical inertia, how much features of the
language, and how much self-fulfilling prophecy isn't really relevant. When
I can take a 10 year old screen-oriented program written for Version 7 UNIX
and run it on an IBM-PC under MS-DOS, then take the same source and compile
and run it under both System V and BSD UNIX, it's going to take more than
theoretical arguments about safety to make me change. It's going to take
working code.

For what other language can I get compatible compilers for:

	UNIX
	IBM-PC
	Amiga
	Atari ST
	Macintosh
	RSX-11/M
	VAX/VMS
	RMX-86

The only other language system that came close was UCSD Pascal, and it's dead.
-- 
 _--_|\  `-_-' Peter da Silva. +1 713 274 5180. <peter@ficc.uu.net>.
/      \  'U`
\_.--._/
      v

mccarrol@topaz.rutgers.edu (Mark C. Carroll <MC>) (03/22/90)

In article <2605a117.396e@polyslo.CalPoly.EDU> jdudeck@polyslo.CalPoly.EDU (John R. Dudeck) writes:

] In article <5200048@m.cs.uiuc.edu> robison@m.cs.uiuc.edu writes:
] ]Why is pointer arithmetic denigrated so much?
] ]
] ]Can anyone clue me as to the basis for pointer paranoia?
] 
] I look at it as relating to the temperament of the programmer.  Different
] people just respond better to different approaches.  It is exactly the
] same issue as the debate between the Mac and the PC.  Some like a system
] that provides you with a Good Way to do whatever you want to do (i.e.
] the Mac and Ada) and others like a system that lets you pick your way
] of doing it (i.e. the PC and C).  The first way gets the job done and
] doesn't let you make mistakes.  The second way gives you a lot more
] flexibility, but you have to learn more and maybe work a little harder
] to get it right.
] 

Sorry. I couldn't let this float by.

Unrestrained pointers are the data structures equivalent of
uncontrolled GOTOs. A language like C that lets you do anything
in the world that you please with pointers is very similar to a
language like BASIC that lets you arbitrarily jump to anyplace you
want to in your code. Sure, there's a lot of power in that! But
there's a lot of unnecessary "danger". 

] There are many different ways to map a problem onto a computer-based
] solution.  Different programming backgrounds lead a programmer to 
] find his solution in a different way.
] 
] I really think that those who are opposed to C, pointers, and all that
] goes with it, are more motivated by a desire to have programming done
] by grunt laborers in a DP shop environment, and have better productivity
] than has been had in the past with Cobol and Basic.  Those who like
] C are more of the craftsman type that like to produce finely wrought
] masterpieces.
] 

This is something that's always annoyed me. Pure language snobbery!
"People who program in MY language are the craftsmen", etc.
Craftsmanship in programming is largely independant of the language
that you program in. I happen to like Eiffel a lot, and I think that
some of my Eiffel code is rather beautiful, in a strange way. But this
doesn't mean that it's a natural property of Eiffel that people who 
write beautiful code are going to gravitate towards it. 

The fact that the C language allows complete, unrestrained
manipulation of pointers is, in my opinion, a severe disadvantage
to the language. Defenses of it remind of some papers that I've
had to read defending the GOTO. I sincerely believe that higher level
control constructs are prefereable to GOTOs; I equally sincerely
believe that higher level data-structures (like the Eiffel implicit
references) are preferable to unrestrained pointers.

] Of course this is just my point of view...
]

And this is just mine. If it sounds a little bit harsh, I'm sorry. I
don't mean for it to come off as a flame.

] John Dudeck 

	<MC>
-- 
\ Mark Craig Carroll: <MC>  |"Don't believe what your eyes are telling you. /
/ Student SysProg - LCSR    | All they show is limitation. Look with your   \
\ Rutgers University        | understanding, find out what you already know,/
/ mccarrol@topaz.rutgers.edu| and you'll see the way to fly." -Richard Bach \

jamiller@hpcupt1.HP.COM (Jim Miller) (03/22/90)

>>Can anyone clue me as to the basis for pointer paranoia?
>
>Programming languages such as Common Lisp and Smalltalk ...


Yes, C is a bad language.  But the better languages that are offered are
not known for their speed.  That is one reason why I prefer to program in C
whenever possible.  Often there are things I need to do which pointers (or
PEEK and POKE in Basic) are the only way to go -- or wait for the language
to be extended and wait and wait :-)

But since C is so bad, why are all you programming in C?  Surely you
can program in your favorite language instead?  Now there are a few
of you out there who are tring to convert us canibals to be civilized,
and I thank you.  But you can't all be missionaries, can you?  If so
then from the traffic on comp.lang.c, there are more missionaries than
us canibals.

peter@ficc.uu.net (Peter da Silva) (03/22/90)

> Unrestrained pointers are the data structures equivalent of
> uncontrolled GOTOs. A language like C that lets you do anything
> in the world that you please with pointers is very similar to a
> language like BASIC that lets you arbitrarily jump to anyplace you
> want to in your code.

C *is* a language that allows you to jump anywhere you want in your code.
By using longjmp and goto you have nearly as much freedom as you do in
Basic (or, more, assembler). If only you could assign gotos, it'd be
perfect [1]. Think of it as a very portable very high-level assembler [2].

[1] Ever implemented an interpreter?
[2] Well, actually, that's Forth...
-- 
 _--_|\  `-_-' Peter da Silva. +1 713 274 5180. <peter@ficc.uu.net>.
/      \  'U`
\_.--._/
      v

billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe, 2847 ) (03/22/90)

From article <D_D27L1xds13@ficc.uu.net>, by peter@ficc.uu.net (Peter da Silva):
>> What is this wonderful "power" which C is giving me, which requires
>> me to live with all the pitfalls?
> 
> There are only two languages I know of in which you can take a moderately
> complex program and run it, without modification, on a wide variety of
> platforms.  One is Fortran, with the Software Tools library.  The other 
> is C... When I can take a 10 year old screen-oriented program written for 
> Version 7 UNIX and run it on an IBM-PC under MS-DOS, then take the same 
> source and compile and run it under both System V and BSD UNIX, it's going
> to take more than theoretical arguments about safety to make me change. 
> It's going to take working code.  For what other language can I get 
> compatible compilers for: UNIX, IBM-PC, Amiga, Atari ST, Macintosh,
> RSX-11/M, VAX/VMS, RMX-86?  

   Ada has validated compilers for a very wide variety of platforms,
   several hundred compilers in fact.  I doubt that the Amiga and Atari
   are among them, due to their small size, but above a certain threshold
   Ada is pretty much universally available and almost totally portable.

   Due to the no-subsets, no-supersets policy, backed up by the compiler
   validation testing requirement, Ada software is highly portable.  The
   main source of portability problems has been operating system-dependent 
   things such as screen I/O, and the preferred technique has usually been
   to isolate such things in small, well-defined packages whose package body
   (implementation) is adapted to the new environment.  But I know, you want
   total, don't-lift-a-finger portability.  Well, so does the Ada community.
   And the result has been CAIS, the Common APSE Interface Set.  There is
   now a process by which CAIS is being merged with PCTE, the European
   Portable Common Tool Environment (or words to that effect), and soon
   we will have a worldwide standard for the interface to operating system
   support facilities.  There is also a validation system for CAIS which
   (the validation system) began formal testing in December 1989 and will
   soon be released.  Combined with the Ada 9X move toward standardizing
   with respect to multinational character sets and the like, there should
   soon be a level of transportability which far exceeds that of C code.

   OK, but it's not here yet, you say... well, that's true.  But there is
   relatively little difficulty associated with porting Ada systems now,
   and in my view the code engineering benefits associated with the Ada
   language far outweigh any minor, short-term porting adaptations which
   might be associated with linking to a particular operating system's
   screen I/O facilities.  In case it's *that* important that you be able
   to not lift a finger, maybe it would indeed be best to wait a few years.
   If you want controlled studies on the performance of CAIS implementations
   on different platforms, add on a few more years.   If you want to be 
   able to get a free copy of CAIS for your machine as well, simply hold 
   your breath until one becomes available.  (Just kidding!!!)   There
   does come a point, though, at which any particular aspect such as
   level of portability has to be considered in relation to other factors
   such as amount of reduction in the length of the testing phase -- 98%
   (vs. 100%) portability, combined with a steep reduction in testing and
   maintenance costs, is probably an extremely reasonable tradeoff to make.


   Bill Wolfe, wtwolfe@hubcap.clemson.edu
 

robison@m.cs.uiuc.edu (03/22/90)

>  /* Written 4:17 pm Mar 20, 1990 by preston@titan.rice.edu in comp.lang.misc*/
>  In article <5200048@m.cs.uiuc.edu> robison@m.cs.uiuc.edu writes:
>  
>  >Can anyone clue me as to the basis for pointer paranoia?
>  
>  Just because I'm paranoid doesn't mean I'm stoopid.
>  
   [Followed by examples of pointer arithmetic and commentary that 
   pointer operations may take more than one machine instruction.]

This is a curiously counter-revolutionary argument against pointer 
arithmetic.  Every other argument that I've seen has said that pointers are 
a too *low-level* construct.  The remarks about hidden multiplications
in pointer addition apply equally well to array indexing, so I fail
to see why pointers are any more demonic than arrays.  I grant the 
objection to pointer subtraction.  I tend to avoid it for exactly the 
reasons given.

- Arch D. Robison

randy@ms.uky.edu (Dan Chaney) (03/22/90)

In article <5200048@m.cs.uiuc.edu> robison@m.cs.uiuc.edu writes:

>This is not the first attack on pointer arithmetic that I have seen.
>Why is pointer arithmetic denigrated so much?  The C-style pointer
>arithmetic seems to me to implement a fairly simple abstraction,
>roughly equivalent to ``a tape and a read/write head.''
>Most C implementations do not do bounds checking on pointers, 
>but I fail to see why pointer arithmetic is inherently evil.
>
>Can anyone clue me as to the basis for pointer paranoia?

I belive the whole thing can be illustrated with one example.  I was 
writing a client as a programming assignment just yesterday, and I ran into
a strange bug.  A variable I though was limited 0..4 was very occasionaly
getting values in the 10,000's.

It turned out, in a different file far away from this variable, I was 
calulating the length of a buffer off by one, and I was overwriting the first
byte of the variable.  Most of the time, it was a zero  overwriting a zero,
but not always.

To make things worse, I could not use the 'trace' feature of dbx because
that slooows things way down, and in networking things happen in real time.
I was sure that I had a pointer error, but it was NOT obvious where, or what
to do.

Yes, this was a programming error on my part.  And yes, I know "only 
experts should use C", but then again I think I'm an O.K C programmer.
The problem with pointer arithmatic without range checking is that
this sort of error will occure from time to time, even for "experts",
and it is very hard to fix.

P.S.  For the guy who wanted bug stories, here's mine.

Randy

-- 
----------------------------------------------------------------------------
Woody Allen: "Your skin, it is so beautiful!"
Mia Farrow:  "Yes, and it covers my whole body, too"
-----------------Randy Appleton - randy@ms.uky.edu--------------------------

gudeman@cs.arizona.edu (David Gudeman) (03/22/90)

In article  <33316@brunix.UUCP> drc@cs.brown.edu (David R. Chase) writes:
>In article <5200048@m.cs.uiuc.edu> robison@m.cs.uiuc.edu writes:
>>This is not the first attack on pointer arithmetic that I have seen.
>>Why is pointer arithmetic denigrated so much?  The C-style pointer
>>arithmetic seems to me to implement a fairly simple abstraction,
>>roughly equivalent to ``a tape and a read/write head.''
>
>Well, one good reason is that in many cases where it pays to do
>pointer arithmetic (loop invariant code, reduction in strength,
>redundant expression elimination), the compiler can do (using
>algorithms published more than 5 years ago) about as good a job as you
>can, except that it won't occasionally make mistakes, and it will
>remember to get it right again when the code is modified.

It seems that most C pointer critics (like this one) are making the
assumption that pointers are used only to avoid inefficiency in array
indexing.  Quite the contrary.  I do a lot of C programming, and I
choose beteen the array abstraction and the pointer abstraction by
whichever fits the problem better.

Pointers are just another form of abstraction, one that a lot of
people find quite useful and intuitive.  I have seen several comments
that pointers are a "low-level" mechanism.  This strikes me as a
content-free statement.  Just how is "low-level" being defined?
-- 
					David Gudeman
Department of Computer Science
The University of Arizona        gudeman@cs.arizona.edu
Tucson, AZ 85721                 noao!arizona!gudeman

gudeman@cs.arizona.edu (David Gudeman) (03/22/90)

In article  <4869@vanuata.cs.glasgow.ac.uk> jack@cs.glasgow.ac.uk (Jack Campin) writes:
>[about C style pointers]
>Thirdly, the aliasing it enables is a semantic mess.  If anyone claims
>different, let's see your denotational model of ANSI C.

Sure, but first show me your denotational model of Ada.

Seriously though, there is nothing unusually complex about the
semantics of pointers.  In fact, the traditional model of stores uses
pointers (usually called "locations") anyway.  The only things that
have to be added are (1) a new data type (pointer) that includes, not
only a location, but also an indication of what the pointer points at
and any index constraints, and (2) operations on the new data type.
One workable implementations is defining a pointer as a triple, and
defining operators to do the appropriate range checks.  Incrementing a
pointer past the bounds of its array is an undefined operation.

The description is not simple, but then almost no substantial
programming language feature is simple to describe mathematically.
-- 
					David Gudeman
Department of Computer Science
The University of Arizona        gudeman@cs.arizona.edu
Tucson, AZ 85721                 noao!arizona!gudeman

nick@lfcs.ed.ac.uk (Nick Rothwell) (03/22/90)

In article <D_D27L1xds13@ficc.uu.net>, peter@ficc (Peter da Silva) writes:
>There are only two languages I know of in which you can take a moderately
>complex program and run it, without modification, on a wide variety of
>platforms.
>
>One is Fortran, with the Software Tools library.
>The other is C.
>it's going to take more than
>theoretical arguments about safety to make me change. It's going to take
>working code.

Which is a quite reasonable argument. Pointer-safe languages generally
require garbage-collected heaps, which means size. So I can see that
a language like C which is required to run on Machines With Tiny
Brains will not be "safe" in that respect.

But, this leaves two issues open: (i) why C has such an idiotic
syntax, arbitrary type-checking, lax compile-time checks and so on,
and (ii) why people think that C's features provide "power" in
general-purpose programming. Point (i) is an accident of history.
Point (ii) still intrigues me.

>For what other language can I get compatible compilers for:
>	UNIX
>	IBM-PC
>	Amiga
>	Atari ST
>	Macintosh
>	RSX-11/M
>	VAX/VMS
>	RMX-86

I find that C's adherence to an implementation-defined word size limits
portability anyway; but I don't think that's an avoidable problem.

>The only other language system that came close was UCSD Pascal, and
>it's dead.

And we mourn its passing. Full PASCAL and screen editor in 56K.
Them were the days.

> _--_|\  `-_-' Peter da Silva. +1 713 274 5180. <peter@ficc.uu.net>.

		Nick.
--
Nick Rothwell,	Laboratory for Foundations of Computer Science, Edinburgh.
		nick@lfcs.ed.ac.uk    <Atlantic Ocean>!mcsun!ukc!lfcs!nick
~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~
      A prop?   ...or wings?      A prop?   ...or wings?      A prop?

peter@ficc.uu.net (Peter da Silva) (03/22/90)

>    Ada has validated compilers for a very wide variety of platforms,
>    several hundred compilers in fact.

That's nice. But are they compatible in the all-important O/S interface
libraries? That's where most languages fall flat on their face. I know ADA
is supposed to provide it's own O/S, but we all know how popular standalone
programs are these days...

>    main source of portability problems has been operating system-dependent 
>    things such as screen I/O, and the preferred technique has usually been
>    to isolate such things in small, well-defined packages whose package body
>    (implementation) is adapted to the new environment.

That technique is no particular virtue of ADA, and it's no particular virtue
at all. You can do the same in any language. The point is that in C that part
has already been standardised. And not just for screen I/O. I don't know how
far ADA goes into file I/O (the book I have on it doesn't mention files at
all), but the C file model happens to be widely portable and broad enough for
most purposes.

As you say, there *will be* a standard. Well, we'll see. When I can copy files
and type "make" and expect the program to compile and run I'll believe it.

>    In case it's *that* important that you be able
>    to not lift a finger, maybe it would indeed be best to wait a few years.

But I've *been* programming in C for ten years now. Why should I wait for
your all-singing all-dancing standard? Dozens of languages have come out with
the same promises you've just made. None of them have delivered.

Why don't *you* wait a few years until portable ADA is real before trying
to convince folks to leave something that works?

One of the BIG advantages of ADA is supposed to be software reusability. If
you can't reuse the software merely because you've upgraded to a SPARC from
your old VAX, what good is it?
-- 
 _--_|\  `-_-' Peter da Silva. +1 713 274 5180. <peter@ficc.uu.net>.
/      \  'U`
\_.--._/
      v

anw@maths.nott.ac.uk (Dr A. N. Walker) (03/23/90)

In article <4869@vanuata.cs.glasgow.ac.uk> jack@cs.glasgow.ac.uk
(Jack Campin) writes:

>> Can anyone clue me as to the basis for pointer paranoia?
>
>Garbage collection, for one.  If you try to implement a BCPL-family
>language on a machine/OS with garbage-collected object memory [i.e. a
>storage model a bit more sophisticated than a Turing machine], you have
>real problems identifying what objects are still being referenced when
>pointers can be incremented.

	But pointers can't be incremented off the current object, so
the problems are exactly the same for C and Pascal and any other language
for which this is a problem at all.  Object-bounds checking in C is
exactly as hard or easy as array-bounds checking in other languages, so
is often "switched off", but that's a different matter.  Or are you
talking about the inherent insecurities of the "malloc ... free" model
of heap storage?  If so, this again applies to Pascal, but not to other
languages with proper heap mechanisms.  In any case, it's a solved
problem.

>Secondly, real machines are sufficiently different from the Turing tape
>that the result of a pointer arithmetic operation is not merely wordsize-
>dependent like normal computer "arithmetic", it's OS-dependent.  Or do C
>fans think it's a good idea to have operator semantics vary with the host
>segmentation scheme?

	I don't understand this either.  There is no interesting difference
between
		pa = pa + 5;	/* pa points into an array */
and
		j = j + 5;	/* j is being used as an index */

except that if the index or pointer is now illegal, the pointer may be
detected instantly whereas the index can't be caught until it is next
used.  One up to pointers?  (If j is a ranged type, the error may then
also be caught here, but that's a less flexible solution.)

>Thirdly, the aliasing it enables is a semantic mess.  If anyone claims
>different, let's see your denotational model of ANSI C.

	Well, I hate denotational semantics, so no offers, but again I
don't understand the problem.  Yes, aliassing is a problem for optimising
compilers, and if used casually is a problem for program-proving;  but
exactly the same problems arise with arrays, so this isn't a pointer
problem, even less a pointer arithmetic problem.

	Summary:  the question was about pointers, but the answers seem
to apply to any aliasable or indexable construction, and we're not yet
being told that C/Pascal/Fortran/whatever shouldn't have arrays.  Or are
we?  Or am I missing Jack's point?

-- 
Andy Walker, Maths Dept., Nott'm Univ., UK.
anw@maths.nott.ac.uk

adrian@mti.mti.com (Adrian McCarthy) (03/23/90)

In article <D_D27L1xds13@ficc.uu.net> peter@ficc.uu.net (Peter da Silva)
writes:
>There are only two languages I know of in which you can take a moderately
>complex program and run it, without modification, on a wide variety of
>platforms.
>
>One is Fortran, with the Software Tools library.
>The other is C.
>
>Which would you rather use?
[edited]
>For what other language can I get compatible compilers for:
>
>	UNIX
>	IBM-PC
>	Amiga
>	Atari ST
>	Macintosh
>	RSX-11/M
>	VAX/VMS
>	RMX-86
>
>The only other language system that came close was UCSD Pascal, and it's dead.
>
>-- Peter da Silva

I usually try to stay out of these, and I'm not trying to upset anyone.

There is no compatible C compiler for UNIX and VAX/VMS, and there can't be
because there are too many fundamental differences between these operating
systems.

The most obvious example of this is linkage.  VAX C had to introduce two
keywords "globaldef" and "globalref" to supplement "extern" in order to make
linkage work as C dictates.  (I'm not sure how GNU C handles this, but I'd
be interested in hearing about it.)  Another obvious example is the different
syntax for filenames, which affects not only how include files are designated,
but also requires the programmer to #ifdef his code to build the right syntax
for run-time data files.  I'd also venture a guess that signals require
some basic differences.

Now if you want to talk about *actual code* that's out there that you
can drop into either environment, the field narrows considerably.  I have yet
to see a C program written in VMS or UNIX environment that sticks strictly
to the standard library *and* uses it correctly.  Things like types.h,
setitimer(), getopt(), fork(), and curses are *not* in the library.  Although
the standard library requires the presence of things like gmtime(), that
doesn't mean a program can rely on them -- the standard allows gmtime() to
return NULL if GMT time isn't available on the host system.  system() calls
obviously require a different syntax (assuming the same function is even
available) and have system-dependent return values.  And how many C
programmers out there realize that external variables are not necessarily
case-sensitive and that they are only guaranteed to be unique to six
characters?

In summary, C compilers can asymtotically [sp?] approach compatibility,
but the amount of portable code out there will remain rather small.  I'm
not flaming C; I'm merely pointing out that strictly ANSI C-compliant code
is no more or less portable than any other well standardized language such
as FORTRAN or Pascal except that C has the advantage of its preprocessor
which lets host-dependent operations to be enumerated with #ifdef.  The
reason so few people stick strictly to the standards (of any of the languages
mentioned here) is because it almost always fails to have enough power
to get the given job done without system-dependent extensions.

Exercise for the reader:  write a *portable* program in any language which
takes a file name as its parameter and returns the modification or creation
date and time of that file.  Don't use any conditional compilation.

Aid.

jamiller@hpcupt1.HP.COM (Jim Miller) (03/23/90)

>
>Unrestrained pointers are the data structures equivalent of
>uncontrolled GOTOs. A language like C that lets you do anything
>in the world that you please with pointers is very similar to a
>language like BASIC that lets you arbitrarily jump to anyplace you
>want to in your code. Sure, there's a lot of power in that! But
>there's a lot of unnecessary "danger". 

The problem with BASIC (and FORTRAN) is that there used to be no other
way!  The lack of a good way forced sole use of the bad.

>The fact that the C language allows complete, unrestrained
>manipulation of pointers is, in my opinion, a severe disadvantage
>to the language. Defenses of it remind of some papers that I've
>had to read defending the GOTO. I sincerely believe that higher level
>control constructs are preferable to GOTOs; I equally sincerely
>believe that higher level data-structures (like the Eiffel implicit
>references) are preferable to unrestrained pointers.

Allowing is not bad, no acceptable alternatives is bad.

I remember taking a course that stressed structured programming, when
I used a GOTO, the TA wrote a GASP! in red on the listing -- but I lost
no points because the alternates were horrible to contemplate.  
(The situation was 2 levels deep in WHILE statements and about 3 deep
in nested IF's and a error was detected.)  The code was considered easy to
read (by the TA) and the purpose of the GOTO was easy to understand.  The
point here and in the other 5 times I've used goto's in my programming, is
that the goto is sometimes the best way.  Or so I have thought so at those
times.  I do not like languages which have pre-determined what is good for
me and the application which the authors know nothing about.
(I don't count the GOTO's I've coded in BASIC, FORTRAN, or assembly
languages, simply because there was no other way)

This is not meant to be a flame for GOTO's, rather against taking basic
functionality out of languages because they might be misused.  Rather,
add functionality which will result in the bad practice being unnecessary.
When it is easier to code the "good" way, the "bad" will (slowly)
stop being used.  For instance, I have seen very few GOTO's in the
last several years in anybody's code where the language had reasonable
other constructs -- even though the dreaded GOTO was available.

If the bad construct continues to be used, one of two reasons will
be in evidence: 1) not enough education, or more likely 2) the
alternative is not sufficient in the user's (not in the inventor's)
opinion.

    jim miller - it's my opinion so it's the truth :-)

peter@ficc.uu.net (Peter da Silva) (03/23/90)

> There is no compatible C compiler for UNIX and VAX/VMS, and there can't be
> because there are too many fundamental differences between these operating
> systems.

I dont think that's the case. As far as I can tell, every place where the
VAX compiler is substantially different from the UNIX compiler has been a
gratuitous change. For example, the use of:

	#include stdio

instead of:

	#include <stdio.h>

C does not require that there actually be a file called "stdio.h" anywhere
on the system. It just requires that it be available in a standard place.
Like a library. Then there's the ref/def problem:

> The most obvious example of this is linkage.  VAX C had to introduce two
> keywords "globaldef" and "globalref" to supplement "extern" in order to make
> linkage work as C dictates.

Again, there are other systems with ref/def semantics where C functions quite
well without new magic words. In every case it is possible to determine
whether a given use of the keyword extern should be interpreted as a PUBLIC
or an EXTERNAL (globalref or globaldef). And it's acceptable for a C compiler
to refuse to accept a program that depends on the traditional fortran/common
semantics of globals.

The fact that Eunice runs under VAX/VMS and provides a fairly conventional
UNIX programming environment puts paid to any claim that VAX/VMS itself
requires any of the gratuitous incompatibilities that DEC has peppered its
compiler with.

Again, other people deal with filename syntax differences. I work with three
syntaxes myself right now: "/path/.../file", "dev:path/file", and ":DV:file".
It just requires a little encapsulation. I have in the past attempted to get
some interest in standardising this encapsulation, with little luck. In any
case, most programs don't need to parse file names... they can treat them as
magic cookies.

> In summary, C compilers can asymtotically [sp?] approach compatibility,
> but the amount of portable code out there will remain rather small.

but at least in C you have a running chance at doing it. There are (except for
a few cases like DEC's) no gratuitous incompatibilities between machines. And
even for DEC portability is within reach. I myself ported a version of Make
from MS-DOS to VAX/VMS, about 3 years ago, because I needed to. It was not
overwhelmingly painful... despite DEC's hostile attitude towards C.

> Exercise for the reader:  write a *portable* program in any language which
> takes a file name as its parameter and returns the modification or creation
> date and time of that file.  Don't use any conditional compilation.

Well, I can do it for any system where the C library is produced by a third
party with some interest in maintaining compatibility. I'll just call stat().
-- 
 _--_|\  `-_-' Peter da Silva. +1 713 274 5180. <peter@ficc.uu.net>.
/      \  'U`
\_.--._/
      v

jlg@lambda.UUCP (Jim Giles) (03/23/90)

From article <1990Mar22.181947.27026@maths.nott.ac.uk>, by anw@maths.nott.ac.uk (Dr A. N. Walker):
> [...]                          Yes, aliassing is a problem for optimising
> compilers, and if used casually is a problem for program-proving;  but
> exactly the same problems arise with arrays, [...]

NO!  The same problem does NOT arise with arrays.  Two different arrays
are two different objects.  Period.  Two different pointers might both
point to the SAME object.  This behaviour of pointers is not only legal
in all languages, it is encouraged.

Yes, it is true that most implementations don't check arrays to make sure
that no aliasing has occurred.  But, the implementor can optimize array
usage with a clear conscience - after all, only illegal programs get
broken.  Pointer usage cannot be optimized this way.  Further, arrays
CAN be tested to make sure illegal aliasing has not occurred - it costs
about the same as bounds checking.  Pointers cannot be tested in this manner
because it is _LEGAL_ for them to be aliased!

[I know - still beating the same dead horse.  This issue NEVER seems to
go away.]

J. Giles

robison@m.cs.uiuc.edu (03/23/90)

/* Written 2:31pm Mar 21, 1990 by mccarrol@topaz.rutgers.ed in comp.lang.misc*/
>
> Unrestrained pointers are the data structures equivalent of
> uncontrolled GOTOs. A language like C that lets you do anything
> in the world that you please with pointers is very similar to a
> language like BASIC that lets you arbitrarily jump to anyplace you
> want to in your code. Sure, there's a lot of power in that! But
> there's a lot of unnecessary "danger". 

I think a closer analogy is the following:

	Control flow		Data flow
	------------		---------
	label			r-value
	goto			assignment

To see the connection, observe what control flow does to the 
program counter (instruction pointer).  This would lead one to 
conclude that any imperative language is "dangerous", whether 
it has pointers or not.  

Arch D. Robison
University of Illinois at Urbana-Champaign

UUCP: {pur-ee,convex}!uiucdcs!robison
Internet: robison@CS.UIUC.EDU

lgm@cbnewsc.ATT.COM (lawrence.g.mayka) (03/23/90)

In article <970@mti.mti.com> adrian@mti.UUCP (Adrian McCarthy) writes:
>Exercise for the reader:  write a *portable* program in any language which
>takes a file name as its parameter and returns the modification or creation
>date and time of that file.  Don't use any conditional compilation.

Common Lisp:

(FILE-WRITE-DATE file)

'file' can be a file name or a stream that is open to a file.
This returns the time at which the file was created or last
written as an integer in universal time format, or NIL if this
cannot be determined.


	Lawrence G. Mayka
	AT&T Bell Laboratories
	lgm@ihlpf.att.com

Standard disclaimer.

emuleomo@paul.rutgers.edu (Emuleomo) (03/23/90)

With all this ranting and raving about the evils of pointer arithmetic
in C, do people realise that it may not have been possible to implement
C++ in C (i.e. cfront translator) without using these evil pointers?
Futhermore, how come C is rapidly becoming the most popular 
application implementation language in the world if it is sooo evil?
In fact, most PC applications (Lotus 1-2-3, Foxbase+, Wordperfect etc...)
are being written in C!!!
I say, like capitalism, let the market (users) decide the going price
(favourite language) for the product.
Remember that Ada, despite DOD funding, is languishing! I daresay that even
Forth, an entirely user driven language, is more popular. 
(No disrespect to Forth whatsoever)


--Emuleomo O.O. (emuleomo@yes.rutgers.edu)
-- 
** The ONLY thing we learn from history is that we don't learn from history!

seanf@sco.COM (Sean Fagan) (03/23/90)

In article <970@mti.mti.com> adrian@mti.UUCP (Adrian McCarthy) writes:
>There is no compatible C compiler for UNIX and VAX/VMS, and there can't be
>because there are too many fundamental differences between these operating
>systems.

Gosh, really?  And I thought there were no grammar changes for GCC under
VMS!

Combine this with a properly-written library and linker, and you should have
what you want.

-- 

-----------------+
Sean Eric Fagan  | "Time has little to do with infinity and jelly donuts."
seanf@sco.COM    |    -- Thomas Magnum (Tom Selleck), _Magnum, P.I._
(408) 458-1422   | Any opinions expressed are my own, not my employers'.

mph@lion.inmos.co.uk (Mike Harrison) (03/23/90)

In article <19253@megaron.cs.arizona.edu> gudeman@cs.arizona.edu (David Gudeman) writes:
> ...
>It seems that most C pointer critics (like this one) are making the
>assumption that pointers are used only to avoid inefficiency in array
>indexing.  Quite the contrary.  I do a lot of C programming, and I
>choose beteen the array abstraction and the pointer abstraction by
>whichever fits the problem better.
>
>Pointers are just another form of abstraction, one that a lot of
>people find quite useful and intuitive.  

Quite true, but for use of the abstraction you do not need an unrestricted 
ability to 'point' at any old thing!


>                             ...  I have seen several comments
>that pointers are a "low-level" mechanism.  This strikes me as a
>content-free statement.  Just how is "low-level" being defined?

"Low level" in a way entirely analogous to that in which 'goto' is
"low level".

You can build loops and conditional structure by using 'skip' statements
and 'goto' statements, but everyone would now agree (? :-) that (except
perhaps for *very* special cases) it is far safer to use the "high level"
abstractions such as 'if ... then ... else' or 'for ... loop' etc.

Similarly you *can* build linked data structures by using pointers and an
'address-of' operator.
The problem is not pointers per se, it is the unrestricted ability to build 
'pointer values'.

Most modern languages give you a 'reference' mechanism, either through a 
restricted (and relatively safe) kind of point (cf. Ada's access types) or
by an even higher level abstraction such as the sequence, (in this case, for
functional languages there will be a mechanism such as th Y [or recursive]
combinator, some 'dressed up' version such as 'letrec' to let you build
cyclic structures.

Thus, I am not underestimating the power of pointers, just trying to show that
the unrestrictedness of 'raw' C pointers is very rarely needed, and that 
restricted pointers are *far* safer.

In fairness, I should quote one case where I found UNTYPED pointers made life
much easier.
This was in a software emulation of a Graph Reduction Machine, where items on
a stack needed to refer (at different times) to different types of objects.
I wrote this in C and had to 'fake' all pointer types. 
I actually found C 'too' strongly typed in this case :-).

Mike,





Michael P. Harrison - Software Group - Inmos Ltd. UK.
-----------------------------------------------------------
UK : mph@inmos.co.uk             with STANDARD_DISCLAIMERS;
US : mph@inmos.com               use  STANDARD_DISCLAIMERS;

new@udel.edu (Darren New) (03/24/90)

In article <1990Mar22.181947.27026@maths.nott.ac.uk> you write:
>Or are you
>talking about the inherent insecurities of the "malloc ... free" model
>of heap storage?  If so, this again applies to Pascal, but not to other
>languages with proper heap mechanisms.  In any case, it's a solved
>problem.

What about Pascal makes the heap "insecure"?  It is perfectly possible
to have good checking of pointers in Pascal.  The first Pascal
compiler I used would detect both of the following:
   new(p);
   q := p;
   dispose(p);
   xx := q^;
because the block that q pointed to would be marked as "free" (or the
memory page would be unallocated if everything else on it was free too).
It would also detect
   new(p);
   q := p;
   dispose(p);
   new(p);
   xx := q^;
even if p reallocated the same space.  Each pointer had a counter in it
that indicated the number of times that "new" had been called when this
pointer was created, as did each heap block.  Thus, the counter in
q would mismatch the counter in the block that q pointed to, hence causing
a run-time message.   

Uninitialized pointers were cause by the fact that both new() and 
allocation of stack frames put illegal pointer values into memory
that was allocated.

Garbage collection would be easy in Pascal except for variant records.
You know the stack frame format for each procedure and each record,
so you can find all the live pointers in a program (except in
records with variant cases).  

Of course, all this could be turned off by linking with a different
library, so "efficient" programs could be tested and then sped up.
                -- Darren

alawrenc@sobeco.com (a.lawrence) (03/24/90)

From article <970@mti.mti.com>, by adrian@mti.mti.com (Adrian McCarthy):
> In article <D_D27L1xds13@ficc.uu.net> peter@ficc.uu.net (Peter da Silva)
> writes:
>>There are only two languages I know of in which you can take a moderately
>>complex program and run it, without modification, on a wide variety of
>>platforms.
>>
>>One is Fortran, with the Software Tools library.
>>The other is C.
>>
	...
> There is no compatible C compiler for UNIX and VAX/VMS, and there can't be
> because there are too many fundamental differences between these operating
> systems.
	...
> Exercise for the reader:  write a *portable* program in any language which
> takes a file name as its parameter and returns the modification or creation
> date and time of that file.  Don't use any conditional compilation.
> 
> Aid.

	I am becoming very tired of the pedantic declarations of C's
tremendous advantage of being so portable.  I know I can write COBOL code
which will not only compile, but also *execute correctly*, on any computer
with an ANSI COBOL compiler without any source code modifications, except
for one "include" file (for the ENVIRONMENT DIVISION).  On the other hand,
COBOL programs cannot do many of the things C does so well.

	Each language has its advantages and disadvantages, and portability
is relatively low on the list of both.  To write batch oriented commercial
applications on large mini or mainframe computers I will chose COBOL
every time.  To develop operating software on micro and mini's C is the
best choice by far, over any other language.  C++ for graphical systems
and major utility applications, etc.  Each in its own place.

---
On a clear disk you can seek forever.
-------------------------------------------------------------------------
Andrew Lawrence        |  alawrenc@sobmips.sobeco.UUCP
Informaticien Conseil  |  {attcan,mcgill-vision}!sobeco!sobmips!alawrenc
3462 Jeanne-Mance, #1  |
Montreal, Que  CANADA  |  Voice (514) 281-5196

rlk@telesoft.com (Bob Kitzberger @sation) (03/25/90)

In article <Mar.23.06.22.52.1990.14819@paul.rutgers.edu>, emuleomo@paul.rutgers.edu (Emuleomo) writes:
> With all this ranting and raving about the evils of pointer arithmetic
> in C, do people realise that it may not have been possible to implement
> C++ in C (i.e. cfront translator) without using these evil pointers?

The ranting and raving was not about pointers, but pointer arithmetic.
Is there a reason why you'd have to resort to pointer arithmetic in C
to implement a C++ translator?

> Futhermore, how come C is rapidly becoming the most popular 
> application implementation language in the world if it is sooo evil?

Hmm.... McDonald's is also the most popular purveyor of hamburgers...
Sorry, but this "C must be great -- everyone is using it!" view has always
annoyed me.

> Remember that Ada, despite DOD funding, is languishing! I daresay that even
> Forth, an entirely user driven language, is more popular. 

Oh?  Please back up this with some facts.  Bill Wolfe has been rather
effective in posting his facts regarding the popularity of Ada, especially
in the domain of "programming in the large".

> (No disrespect to Forth whatsoever)

And no disrespect to McDonald's, either ;-)

	-- Bob Kitzberger
-- 
Bob Kitzberger                  Internet : rlk@telesoft.com
TeleSoft                        uucp  :    ...!ucsd.ucsd.edu!telesoft!rlk
(619) 457-2700 x163

"you can have quality software, or you can have pointer arithmetic; but you 
 cannot have both..."           -- Bertrand Meyer
------------------------------------------------------------------------------

anw@maths.nott.ac.uk (Dr A. N. Walker) (03/27/90)

In article <14286@lambda.UUCP> jlg@lambda.UUCP (Jim Giles) writes:

>From article <1990Mar22.181947.27026@maths.nott.ac.uk>, by
>anw@maths.nott.ac.uk (Dr A. N. Walker):
>> [...]                          Yes, aliassing is a problem for optimising
>> compilers, and if used casually is a problem for program-proving;  but
>> exactly the same problems arise with arrays, [...]

>NO!  The same problem does NOT arise with arrays.

	OK, I'm not deaf.

>						    Two different arrays
>are two different objects.  Period.

	So, there are some occasions where a compiler can be sure that
a[i] and b[j] are different objects;  and it's relatively harder to be
sure that pa, pb point into different objects.  On the other hand, if
a and b are parameters, they *may* (in C and many other languages) be
the same array, and EXACT... (sorry) exactly the same problems arise.

>				      Two different pointers might both
>point to the SAME object.  This behaviour of pointers is not only legal
>in all languages, it is encouraged.

	What form does this encouragement take?  I often initialise one
pointer by reference to another, but that's just common sense.  It's
hard to imagine that adding a restriction to prevent this would make
anyone's life easier.

	(In similar vein, I once used a language [Babel] in which it was
illegal to assign to a variable twice without the variable being used in
the meantime.  The implementor wisely took a holiday immediately after
adding this feature to his compiler.)

>[...]				 But, the implementor can optimize array
>usage with a clear conscience - after all, only illegal programs get
>broken. [...]

	The question was about C pointer arithmetic.  In C, legal programs
also get broken if potentially aliassed arrays are optimised as though
they are not aliassed.

>[I know - still beating the same dead horse.  This issue NEVER seems to
>go away.]

	Well, it helps if we are all looking at the same horse.  The point
at issue is not whether C or Fortran or Pascal or ... has better arrays, or
better rules about side-effects, but whether pointer arithmetic should be
considered harmful.  Unless someone has a more convincing example than we
have seen so far, the answer is no.  You should use it when it is right to
do so, and not otherwise. [:-)]

>J. Giles

-- 
Andy Walker, Maths Dept., Nott'm Univ., UK.
anw@maths.nott.ac.uk

anw@maths.nott.ac.uk (Dr A. N. Walker) (03/27/90)

In article <14804@nigel.udel.EDU> new@udel.edu (Darren New) writes:
>In article <1990Mar22.181947.27026@maths.nott.ac.uk> you write:

	I guess "you" is "me"!

>>Or are you
>>talking about the inherent insecurities of the "malloc ... free" model
>>of heap storage?  If so, this again applies to Pascal, but not to other
>>languages with proper heap mechanisms.  In any case, it's a solved
>>problem.

>What about Pascal makes the heap "insecure"?  It is perfectly possible
>to have good checking of pointers in Pascal.  The first Pascal
>compiler I used would detect [... first example deleted ...]
>It would also detect
>   new(p); q := p; dispose(p); new(p); xx := q^;
>[... by using counters ...]

	Well, first off, it's hard to make this scheme unspoofable.  If
you have something like:

	new(p); q := p; dispose(p); ...; new(x); ...

where the space for "x" encloses the space for "p", and you now assign
things into that space, how do you know you haven't accidentally created
a legal thing for "q" to point at?  OK, it's a small chance [but not
helped if the counter is indeed the number of calls of "new", and thus
likely to be a small integer].  Clever coding of the library routines
and of the compiler can get around this, especially if the hardware is
on your side.

	Secondly, this technique separates the error from its detection.
The error is to call "dispose" while "q" is live;  the next actual use of
"q" may be right the other end of the program, and it could be disguised
by copying "q" into other pointers, and the "dispose" could be of a copy
of "p", tucked away in some insignificant-looking sub-sub-procedure, etc.
My memory of Pascal is too rusty to be sure whether the above call of
"dispose" is technically illegal, or whether it's only dereferencing "q"
that's illegal.  If the former, then that too could be detected by better
library routines and compilers, but I expect it's the latter, in which
case giving the poor user decent diagnostics is virtually impossible.

	Thirdly, the decision of when to free storage should not be one
for the programmer.  It's intrinsic to heap storage that the freeing is
dissociated from the creation.  It's intrinsic to the more complex data
structures that storage may be linked together in arbitrarily complicated
ways.  So there is no way [except in very simple programs] in which a
procedure can take a decision, based on localisable information, about
which parts of the structures should be freed.  Even when this information
is available, it can be very tedious to keep "fingers" on obsolescent
storage just so that it can be freed eventually.  I conclude that garbage
collection really has to be a matter for the system.

	Fourthly, all this checking takes space and time, so it's the
first thing to go in a production version.  (What was it that Dijkstra
said about using a lifebelt while paddling in the harbour and throwing
it away while swimming out to sea?)  Proper garbage collection costs
nothing in the compiled code [given shared libraries] and little in speed
until the store becomes full;  and it's secure.  Good software engineering.

-- 
Andy Walker, Maths Dept., Nott'm Univ., UK.
anw@maths.nott.ac.uk

burr@st_nik.UUCP (For Steve Burr) (03/27/90)

In article <19255@megaron.cs.arizona.edu>, gudeman@cs.arizona.edu (David Gudeman) writes:
> In article  <4869@vanuata.cs.glasgow.ac.uk> jack@cs.glasgow.ac.uk (Jack Campin) writes:
> >[about C style pointers]
> >Thirdly, the aliasing it enables is a semantic mess.  If anyone claims
> >different, let's see your denotational model of ANSI C.
> 
> Sure, but first show me your denotational model of Ada.
> 
Certainly, A formal specification of ADA is described using
the Vienna Development Method in:

"Towards a formal definition of ADA", D.Bjorner et al
Springer Verlag.

Regards, Steve Burr

jlg@lambda.UUCP (Jim Giles) (03/28/90)

From article <1990Mar26.181444.11727@maths.nott.ac.uk>, by anw@maths.nott.ac.uk (Dr A. N. Walker):
> In article <14286@lambda.UUCP> jlg@lambda.UUCP (Jim Giles) writes:
>> [...]
>>						    Two different arrays
>>are two different objects.  Period.
> 
> 	So, there are some occasions where a compiler can be sure that
> a[i] and b[j] are different objects;

Yes - the 'some occasions' happens to be nearly always: because such
array aliasing is _illegal_.  To be sure, few compilers provide an
option to detect such aliasing.  Such a run-time test would be simple
and would cost about the same as array bounds checking.  The fact that
few compilers provide it indicates that the error is extremely rare.

> [...]                                 and it's relatively harder to be
> sure that pa, pb point into different objects.

That's not the point (so to speak).  The fact is, it's _legal_ for
the two pointers to be aliased.  So, even if you _could_ detect when
they were aliased and when they were not, what would you do with the
information?  Compile all your code both ways (and if there are more
than two pointer args - the number of different aliasing combinations
increases combinatorially) and make a run time decision which version
to use?  Not at all cost effective.

Further, in view of the fact that array args are seldom aliased anyway
(see above about the infrequency of such a thing in languages where
aliasing is not allowed), C must make a pessimizing assumption about
its procedure args in order to support a rarely needed feature.

> [...]                                           On the other hand, if
> a and b are parameters, they *may* (in C and many other languages) be
> the same array, and EXACT... (sorry) exactly the same problems arise.

If a and b are array parameters, then (in most languages) they
*may*not* be the same array (at least, not if the procedure
assigns to either of them).  So, in these languages, the same
problems do not arise.  This is exactly the nature of the weakness
in C that I've been complaining about.

>>[...]				 But, the implementor can optimize array
>>usage with a clear conscience - after all, only illegal programs get
>>broken. [...]
> 
> 	The question was about C pointer arithmetic.

Nice try.  But the statement that I responded to was your claim that
arrays and pointers were the same.  They aren't.  C confuses the issue
by not having a mechanism to pass arrays to procedures - it converts
them to pointers.  I made the claim that C's pointers and arrays were
the same a long time ago and the C community came down on me like a
ton of bricks.  Since then I've learned to be more careful with my
terms.  C has global arrays, local arrays, and something in between
with 'file' scope - C does not have array arguments to procedures.

> [...]                                             In C, legal programs
> also get broken if potentially aliassed arrays are optimised as though
> they are not aliassed.

Exactly!  C must pessimize the code in ways that other languages needn't.

> [...]
>>[I know - still beating the same dead horse.  This issue NEVER seems to
>>go away.]
> 
> 	Well, it helps if we are all looking at the same horse.  The point
> at issue is not whether C or Fortran or Pascal or ... has better arrays, or
> better rules about side-effects, but whether pointer arithmetic should be
> considered harmful.

In other words, you're considering a language design issue involving the
use of pointers.  In C, it's difficult to decouple pointer arithmetic from
array manipulation since the language itself confuses the two.  It is
difficult for me to imagine _any_ language in which questions about
pointers can be decoupled from the issue of aliasing.  As with any other
language design issue, comparison to other languages is a prefectly
appropriate thing to do.

> [...]                 Unless someone has a more convincing example than we
> have seen so far, the answer is no.  You should use it when it is right to
> do so, and not otherwise. [:-)]

Oh, I agree.  You should avoid pointer use of any kind unless the
benefits outweigh the penalty.  The penalty is less readible code
that is poorly optimized because of aliasing.  But, since you mention
it: what context do you think is appropriate for the use of pointer
arithmetic?  Bear in mind that, except for aliasing and bounds checking
differences, pointer arithmetic is semantically _identical_ to array
indexing on a single dimensioned array.  Since pointers are _less_
desireable because of aliasing and bounds checking differences, what
application do you claim an advantage for pointer use?  I can think
of only one - and I suspect it won't be the one you propose - I'll
wait and see.

(All comments about beating dead horses still apply.)

J. Giles

chl@cs.man.ac.uk (Charles Lindsey) (03/28/90)

burr@st_nik.UUCP (For Steve Burr) writes:

>In article <19255@megaron.cs.arizona.edu>, gudeman@cs.arizona.edu (David Gudeman) writes:
>> In article  <4869@vanuata.cs.glasgow.ac.uk> jack@cs.glasgow.ac.uk (Jack Campin) writes:
>> Sure, but first show me your denotational model of Ada.
>> 
>Certainly, A formal specification of ADA is described using
>the Vienna Development Method in:

>"Towards a formal definition of ADA", D.Bjorner et al
>Springer Verlag.

BUT, I rather think this formal definition left out the interesting bits,
notably the tasking, which rather defeats the object of the exercise.

The point is that denotational semantics has to make a big meal of any sort of
nondeterminacy, with the result that even if it can be done it does not lead
to a readily understandable language definition. Moreover, there is also a
temptation to over-define a language.

gudeman@cs.arizona.edu (David Gudeman) (03/30/90)

In article  <10049@st_nik.UUCP> burr@st_nik.UUCP (For Steve Burr) writes:
>In article <19255@megaron.cs.arizona.edu>, gudeman@cs.arizona.edu (David Gudeman) writes:
>> Sure, but first show me your denotational model of Ada.
>> 
>Certainly, A formal specification of ADA is described using
>the Vienna Development Method in:
>
>"Towards a formal definition of ADA", D.Bjorner et al
>Springer Verlag.

Can't say I've read the article, but given that the title begins with
"Towards...", I'll bet it isn't a complete description of Ada.  If you
want a partial description of C, they are fairly common.

Actually, I don't think I've ever seen a complete denotational
description of _any_ real programming language.  The reason for this
is partly the complexity of denotational descriptions, but a more
compeling reason is that there is so much uninteresting detail in such
a description.  I wrote a denotational description of Icon that solved
all the major problems in the language, but didn't bother writing a
definition for every single operator and built-in function (a task
that would be almost as hard as implementing the language).  I also
didn't write the semantics for some complex but "well understood"
features such as "return"s from a function.  There just isn't much
reason for doing those sorts of things.
-- 
					David Gudeman
Department of Computer Science
The University of Arizona        gudeman@cs.arizona.edu
Tucson, AZ 85721                 noao!arizona!gudeman