HDTenEightyP/NetNews huggingface dataset:
From: rmartin@thor.Rational.COM (Bob Martin)
Newsgroups: comp.lang.c++
Subject: Re: Tiny proposal for named loops.
Date: 26 Aug 92 21:17:36 GMT

fjh@munta.cs.mu.OZ.AU (Fergus James HENDERSON) writes:

|rmartin@thor.Rational.COM (Bob Martin) writes:

|>clearly "while (1)" does not fall under your advice to "code what you
|>mean".  However, by using a flag, you can put "what you mean" in the
|>loop condition.

|I disagree. If find while(1), or more preferably for(;;), to indicate
|quite clearly what the programmer means.

Taken literally, it means: "infinite loop", i.e. a loop with no exit
condition.  Clearly, this is not what you mean.

|If the termination condition for a loop is complex, then
|it should be coded as simply as possible - this means using
|goto/break/etc - and documented with comments.

Again, I disagree.  I find this construct:

   while (error == NO && done == NO)

easier to understand than:

   for (;;)

I disagree that breaks are the simplest possible.  They are more
complex becuase they abort rather than terminate the loop.

|While we're on the subject of FSM's and gotos, have a look at this code
|taken from my Turing machine simulator program. This is another good
|example of where gotos are useful. Try rewriting this without gotos!
|(Solutions using exceptions don't count - at least, not until my compiler
|implements them!)

[...parsing code deleted...]

The code was a simple parser which discovered errors in a deeply
nested loop and jumped out of the loop.

Most parsers are finite state machines.  This could have been modeled
as a finite state machine, complete with a state variable and
transition codes.  There are many ways to implement such FSMs without
resorting to gotos.  Such methods are quite resilient to change, since
they directly model the state-transition map.  But indiscrimiate use
of gotos to simulate a FSM can make the FSM difficult to change.


--
Robert Martin                        Training courses offered in:
R. C. M. Consulting                       Object Oriented Analysis
2080 Cranbrook Rd.                        Object Oriented Design
Green Oaks, Il 60048 (708) 918-1004       C++
Xref: sparky comp.lang.c++:13064 comp.std.c++:1119
From: sabroe@daimi.aau.dk (Morten Sabroe Mortensen)
Newsgroups: comp.lang.c++,comp.std.c++
Subject: Dynamic allocation, -what's fastest?
Date: 30 Aug 92 17:16:44 GMT
Organization: DAIMI: Computer Science Department, Aarhus University, Denmark


        I'm wondering about making a data-structure, that can sort elements
real quick, -not "on the the run", but after all elements have been inserted!
Now, -quick-sort isn't that bad,- so I could just use a simpel array! Well,
I could, but then I need a limit on the number of elements, I can insert, and
that's not what I want! No, -I'm thinking about a dobble-linked list; it must
be possible to run quick-sort on that! No matter what's best, it's not that
part, I want you to respond to (but, -feel free to do so anyway!).

        Now, for some reason I want to make a dobble-linked list of, say,
void-pointers! The usual way to do it, is to have one entry in the list
for each inserted element, right? Would such a structure eat less memory, and
,-which is, what I'm really after-, less time, if each entry in the list is
an array of some fixed size, -f.ex. big enough to hold 500 elements? WHY DO
I THINK, that it could be, that it's a good strategy to make a list of arrays
of fixed size? Well, how expensive is 'new' and 'delete' really? Would it be
better to allocate many small memory-blocks, or just a few big memory-blocks?
I'm not surprised, if it's equal expensive to allocate blocks of different
sizes! DOES ANYONE KNOW ANYTHING ABOUT HOW EXPENSIVE 'NEW' AND 'DELETE' 
REALLY ARE? WOULD I GAIN ANYTHING, IF I DON'T USE 'NEW' AND 'DELETE' MORE
THAN ABSOLUTELY NESSESARY?

        What I want to do with the linked list, is insert a lot of elements,
then sort it all, traverse all elements, delete it all (or, if I get better
performance, delete while traversing), and then start all over with a new set
of elements! It would not give me too much trouble to program these two
different strategies, and then run a test on both of them, BUT I really want
to know about this in teory first!

        If anyone knows how time-consuming 'new' and 'delete' are, please
respond! I done through e-mail, I might or might not post a summary!

        -- Morten S. M.
Newsgroups: comp.lang.c++
From: steve@taumet.com (Steve Clamage)
Subject: Re: GOTO, was: Tiny proposal for na
Organization: TauMetric Corporation
Date: Sun, 30 Aug 1992 16:50:16 GMT


In <1992Aug26.130335.26725@hemlock.cray.com> dsf@cray.com (Dan Frankowski) writes:

|I believe someone once wrote an article entitled something like
|"Structured Programming Using Goto"; the same person who wrote
|another article that started this whole mess that was entitled "Goto
|Considered Harmful", if my memory has changed state randomly.

Sorry, your memory needs refreshing :-)

"Go to statement considered harmful" was a letter written to
Communications of the ACM by Edsger Dijkstra and published in
CACM, Vol 11 No 3, March 1968; the was title supplied by the editor.
(Dijkstra has written about this letter elsewhere, and extensively
on the subject of structured programming.  Most everything he has
published deserves serious study; check your local CS or Engineering
library.)

"Structured Programming with go to Statements", by Donald Knuth,
was published in ACM Computing Surveys, vol 6 No 4, December 1974.
It is well worth reading, as is the rest of this issue.
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com
Vice Chair, ANSI C++ Committee, X3J16
From: ilh@lcs.mit.edu (Lee Hetherington)
Newsgroups: comp.lang.c++
Subject: Re: risky inline
Date: 27 Aug 92 22:09:30 GMT
Reply-To: ilh@lcs.mit.edu
Organization: MIT/LCS Spoken Language Systems
In-reply-to: trachos@uni-paderborn.de's message of 27 Aug 92 12:27:00 GMT

What's the big deal?  You defined (in the header file) C::c() to have
EXTERNAL linkage, but then never provided a GLOBAL definition.  For the
sake of linkage, inline is like static (and turns into that if the
function is actually too big to be inlined).  In the library, your
definition of C::c() is not global.  Why is that so unsafe (or surprising)?

The real safety of inline over #define is that you still get type
checking on the arguments and return value.  You also get `overloaded'
function names:

inline int min(int a, int b)
{
	return (a <= b) ? a : b;
}

inline int min(int a, int b, int c, int d)
{
	int ab = min(a, b), cd = min(c, d);
	return min(ab, cd);
}

are two separate functions with the same `name'.  Try that with #define.
--

                                Lee Hetherington
                                ilh@lcs.mit.edu
From: pat@frumious.uucp (Patrick Smith)
Subject: Re: break/continue (was: Re: Tiny proposal for named loops.)
Date: Thu, 27 Aug 1992 00:52:14 GMT
Reply-To: uunet.ca!frumious!pat
Organization: None

johnrp@well.sf.ca.us (John Panzer) writes:
|In article <1992Aug26.040955.593@frumious.uucp> uunet.ca!frumious!pat writes:
|>An error function that stops your program alters the control flow
|>in a nice, simple way.  By contrast, exceptions can have somewhat
|>non-intuitive effects.  Consider this function:
|>
|>   void foo() {
|>      char* p = new char[17];
|>      doSomething();
|>      delete [] p;
|>   };
|>
|>If doSomething() can throw an exception, then foo() has a memory leak!
|
|If doSomething() calls exit(), the program still has a memory leak.
|(Usually the memory is reclaimed by the system so you don't notice,
|but try it with shared memory sometime...)

A good point.  But in most programs one doesn't have to worry about
such things.  Then again, maybe when exceptions are available most
programs won't catch exceptions - they'll just let the program
stop (hopefully with a suitable error message).  So perhaps this
aspect of exceptions won't cause problems for too many people.


|On the other hand,
|in the presence of exceptions you have at least two ways to plug
|the leak:

Quite true.  I wasn't trying to say that exceptions are bad (on the
contrary, I wish I had a compiler that implemented them!).
My point was that they have the potential to play games with
the control flow of one's programs - even in code that doesn't
appear to involve exceptions at all.

-- 
Patrick Smith
uunet.ca!frumious!pat
pat%frumious.uucp@uunet.ca
Newsgroups: comp.lang.c++
From: silvia@rcf.rsmas.miami.edu
Subject: Re: Borland C++ 3.1 Buggy any alternatives?
Reply-To: silvia@rcf.rsmas.miami.edu
Organization: RSMAS
Date: Thu, 3 Sep 92 16:47:47 GMT

In article <H7ZyoB6w164w@cellar.org>, rpost@cellar.org (hamilton) writes:
>I tried to use BC++ 3.1.  It would lock-up my PC if I tried to launch the
>DOS graphics based IDE from Windows.  And the help would fail, under the
>windows IDE version, after I loaded any project.  Their technical help
>was unavailble (after being on hold for over half an hour) and their
>customer support could only tell me how to ship it back.
>
>Evidently, Borland is only concerned with the BIG end user (i.e. Corprations)
>I have given up on them, but am wary of MicroSoft.  Are there any 
>alternatives?
>
>See you in Pittsburgh...

Give Symantec a try.. They make Zortech C++. Its a good compiler with support
for 386 enhanced mode.


           Manolo

Newsgroups: comp.lang.c++
From: checker@acf5.NYU.EDU (checker)
Newsgroups: comp.lang.c++
Subject: Re: Inherited nested classes?
Date: 30 Aug 92 18:23:57 GMT
Organization: New York University

jbn@lulea.trab.se (Johan Bengtsson) writes:
>Are private nested types useful at all, given the current language definition?

Huh?  How else would you have the access control work?  Of course they
are useful:

class list
{
public:
	// ...
private:
	class list_node
	{
		// ...
	}

	list_node *pHead;
};

Chris
From: tmb@arolla.idiap.ch (Thomas M. Breuel)
Newsgroups: comp.lang.c++
Subject: Re: GOTO, was: Tiny proposal for named loops.
Date: 26 Aug 92 02:04:34 GMT
	<rmartin.714668024@thor> <2299@devnull.mpd.tandem.com>
	<rmartin.714749390@thor>
Reply-To: tmb@idiap.ch
Organization: IDIAP (Institut Dalle Molle d'Intelligence Artificielle
	Perceptive)
In-reply-to: rmartin@thor.Rational.COM's message of 25 Aug 92 13:29:50 GMT

After many postings extolling the evils of "break", "return" and other
"non-structured" exits from blocks, Bob Martin writes in article
<rmartin.714749390@thor>:

   In a real application, when confronted with memory outage, I would
   throw an exception, call assert, or just plain exit.

What is an exception exception other than an exit from a block? How is
that going to leave your "pre- and postconditions" intact?

Altogether, I find Bob's arguments against "break" unconvincing. There
is nothing wrong with using "break", exceptions, or even the
occasional "goto" in C++, since C++ has mechanisms (destructors) that
can be used to take care of cleanup jobs when a block is exited from
anywhere; simply use them.

					Thomas.
From: Aurelius@cup.portal.com (Mark Christian Barnes)
Newsgroups: comp.lang.c++
Subject: Re: complex classes and temporary destruction.
Date: Thu, 27 Aug 92 23:44:12 PDT
Organization: The Portal System (TM)
Distribution: world
  <23563@alice.att.com>

Andrew Koenig writes:

| Don't worry, the issues under discussion will not affect well-behaved
| programs such as this.  The real problems come about when, say, a String
| class has operator const char() that returns a pointer to the internal
| representation of the String.  That then raises the problem:
| 
| String s, t;
| 
| // ...
|         const char* p = s + t;
| and now, the question is when the temporary representing `s + t' is
| destroyed.  The point is that destroying that temporary invalidates p, 
| so it suddenly becomes an issue of great concern.
| --
|           --Andrew Koenig

 Have the temporary "inherit" (for lack of a better word) the
storage class of p. If p is an auto variable then 's+t' should
be auto too. Destroy p and 's+t' together. If p is static, then
perhaps have 's+t' be static as well, onc instance of 's+t'
gets re-used each time the statement is executed.

 For global variables, you have to watch out for all kinds of
unknowns. In this case, maybe a destructor should be called
right before p is assigned a new value. This assumes that the
old value of p is no longer needed and the new temporary is not
able to re-use the 's+t' object. Also 's+t' may be assigned to more
than one variable by this time, and therefore should remain around.

String s = "hello";	// global String
const char *pS1, *pS2;	// global pointers

void not_main ( void )
{
 pS1 = s + s;		// assign temporary to global
 pS2 = pS1;		// save a copy
 pS1 = s + s + s;	// assign another temp to global, re-use 's+s'?
			// or maybe destruct 's+s' and create 's+s+s'?
			// But no!, pS1 points to 's+s' also. Since
			// the pointers are always in scope, when
			// do the temporaries get destructed??
}

 This bit of an example may show that the two "temporaries"
could be destroyed or re-used before the assignment. But of
course they may be aliased again outside the scope of this
module. About all that makes sense to me is that they are
not actually "temporary" at all, but are unnamed globals,
whose usage needs to be tracked by the compiler.

			Regards, Aurelius@cup.portal.com
From: rmartin@thor.Rational.COM (Bob Martin)
Newsgroups: comp.lang.c++
Subject: Re: Destruction of temporaries
Date: 31 Aug 92 13:49:52 GMT

ark@alice.att.com (Andrew Koenig) writes:

|In article <rmartin.715101472@thor> rmartin@thor.Rational.COM (Bob Martin) writes:

|> No, I want a warning every time a temporary gets converted into a
|> pointer.  

|All that will do is cause library authors to write little classes
|that contain pointers to suppress warnings.  Or maybe they'll use
|explicit member function calls instead of implicit conversions.

These strategies should not supress the warnings.  ANY time an address
or reference to a temporary is taken, whether is is via implicit
conversion, or as the argument of a member function, a warning should
be issued.  No exceptions.

This will flag every instance where a long lived alias to a temporary
could be created.  Unfortunately it will also flag the creation of
perfectly benign aliases.  As I said in an earlier post, compiler
writers could implement #pragmas which allowed programmers to
name functions which were known to create benign aliases.  


--
Robert Martin                        Training courses offered in:
R. C. M. Consulting                       Object Oriented Analysis
2080 Cranbrook Rd.                        Object Oriented Design
Green Oaks, Il 60048 (708) 918-1004       C++
Newsgroups: comp.lang.c++
From: jimad@microsoft.com (Jim Adcock)
Subject: Re: destruction of temporaries
Date: 25 Aug 92 18:25:38 GMT
Organization: Microsoft Corporation
Keywords: temporaries,destruction,statements,block,early

In article <23487@alice.att.com> ark@alice.UUCP () writes:
|	1. strict end of block destruction creates problems for programs
|	   like this:
|
|		{
|		loop:
|			// do something that creates a temporary here
|			if(cond) goto loop;
|		}
|
|	   If you'really serious about destroying temporaries at end of
|	   block, that means you need a mechanism for allocating potentially
|	   uncbounded stack space and keeping track of all the destructors
|	   so as to be able to undo them all at the end.  This can be a
|	   real pain, especially if you are trying to compile to C.

I don't think people mean to imply that lifetimes of unnamed temporaries ought
to live longer than an equivalent named temporaries.  Both should be subject
to the same "implied block" rewriting rules in the face of loops or 
conditional expressions:

		{
		loop:
			{ // implied
			// do something that creates a temporary here
			if(cond) goto loop;
			} // implied
		}


I suggest that something like the following set of rules would in practice
allow compiler implementations such that all existing conforming
compiler/program pairs could continue to work:

Rules in order of precedence:

1) Lifetimes of unnamed temporaries never exceed their surrounding blocks,
  including the implied rewriting blocks of loops and conditionals.

2) Named temporaries live to the end of their name's surrounding block.

3) Temporaries must live until after their last access or end of block --
whichever comes first.

4) Compilers are allowed to destroy temporaries anytime in any order after
their last access.

====

The above rules shift the burden of temporaries to optimizing compilers.
Niave implementations can simply wait to the end of block [where "block"
includes the implied rewriting rules of loops and conditions].  Optimizing
compilers are free to reclaim objects as soon as they are done being used.
In some cases, this may be very hard for optimizing compilers to determine --
in which case they are free to fall back on the naive scheme.  In practice,
in many cases an optimizing compiler can simply determine last access,
and can optimize lifetimes well.

Under these rules the only difference between named objects and unnamed
objects is the destruction of named objects *must* occur at end of block,
whereas for unnamed objects destruction can occur earlier.

Newsgroups: comp.lang.c++
From: steve@taumet.com (Steve Clamage)
Subject: Re: GOTO, was: Tiny proposal for na
Organization: TauMetric Corporation
Date: Thu, 27 Aug 1992 18:12:45 GMT

dsf@cray.com (Dan Frankowski) writes:

>In article <6800007@tisdec.tis.tandy.com> kevinl@tisdec.tis.tandy.com writes:

>>	For experienced programmers, the goto is a legitamite tactic.
>>There may not be any cases where a goto is absolutly necessary (I've
>>heard that there are some, but I have yet to see any), ..

>I thought that one of the triumphs of the Structured Programming camp
>was an honest-to-goodness proof that any code using gotos could be
>replaced by structured constructs and state variables.

It is a common misconception that this was a triumph for structured
programming.

The paper: Bohm and Jacopini, "Flow diagrams, Turning machines, and
languages with only two formulation rules", Communications of the ACM,
vol 9 no 5, May 1966, p 366-371.

They provide a mathematical proof that any program with goto's can be
transformed into one without them.  The program transformed by their
method is not necessarily a good one, or even understandable.  This
result does not provide a foundation for structured programming, except
in the very limited sense of showing that programming does not
absolutely require goto's.

Structured programming rather provides a framework for containing the
complexity of programs.  You can write a structured program in assembler.
Languages supporting structured programming provide alternatives to
the goto which directly implement structured programming concepts,
reducing the need for goto's.
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com
Vice Chair, ANSI C++ Committee, X3J16
Newsgroups: comp.lang.c++
From: pjl@sparc6.cs.uiuc.edu (Paul Lucas)
Subject: Re: Generic types
Organization: University of Illinois at Urbana-Champaign
Date: Sat, 29 Aug 1992 16:34:33 GMT

In <l9scgqINNh7u@exodus.Eng.Sun.COM> obourdon@France.Sun.COM (Olivier Bourdon - Sun ICNC) writes:

>Let's assume I have two different types of objects (classes)
>//-------------------
>class complex {
>public:
>	int i,j;
>	...
>	void Print();
>};
>//--------------------
>class string
>public:
>	char *str;
>	...
>	void Print();
>};

>and I also have a double linked list
>//-----------------
>class list {
>	void *element;
>	list *next, *prev;
>	void Print();
>};

>then I woul like to do something like :
>void list::Print() {
>	while (this->next!=NULL)
>		this->elem->Print();
>		...
>}

>I know that it does not work AT COMPILE TIME because the Print function is not
>	a member function for void * type. It seems like I could create sur-classes
>	of list by removing the element field in the list class and adding :
>class stringlist {
>	string *element ;
>	...
>};

>but then I have to write 2 times the EXACTLY SAME CODE once for
>stringlist::Print and the other one for complexlist::Print
>and I would like to have only one piece of code so that if I have to
>modify it I do it only at one place

*****>	You have to have a base Link class that has Print() in it from which
	all other things that are to be on the list have to be derived from.
	(This make for what is called an "intrusive list.")  Print() has to
	be virtual.

	You can also decide whether you want the list to be "managed" or
	not, i.e., when the list goes away, does it destroy the elements
	also.  Stroustrup, 2nd ed., has examples of this very thing.  I've
	done things similar to:

		class Link {	// not List since it's just a link in a list
			Link *prev, *next;
			Link *element;
		public:
			// ...
			virtual void Print() = 0;
		};

		class Foo : public Link {
			// ...
		public:
			// ...
			void Print();
		};
-- 
	- Paul J. Lucas				University of Illinois	
	  AT&T Bell Laboratories		at Urbana-Champaign
	  Naperville, IL			pjl@cs.uiuc.edu
Newsgroups: comp.lang.c++
From: nikki@trmphrst.demon.co.uk (Nikki Locke)
Distribution: world
Subject: Re: Novice Questions
X-Mailer: cppnews $Revision: 1.14 $
Organization: Trumphurst Ltd.
Date: Wed, 2 Sep 1992 09:43:09 +0000


In article <1992Aug31.160703.324@ziff.com> jliberty@zdi.ziff.com writes:

> One aside, the orig. author seems to have the whole issue of "nulls"
> confused. It may be worth pointing out that the way c (and c++) checks
> for end of string is with a NULL (or zero). 

I HATE it when people do that ! (:-)

NULL is a POINTER which is guaranteed not to point to any valid location. 
It may or may not have the bit pattern all zeroes.

'\0' (ASCII NUL) is the CHARACTER which is used to terminate strings.

Please do not confuse the novice by using NULL to mean NUL.

---
Nikki Locke              |                        | nikki@trmphrst.demon.co.uk
Trumphurst Ltd.          | Tel: +44 (0)691-670318 | nikki@cix.compulink.co.uk
PC and Unix consultancy  | Fax: +44 (0)691-670316 | nikki@kewill.co.uk
trmphrst.demon.co.uk is NOT affiliated with ANY other sites at demon.co.uk.
Demon.co.uk is a dial-up subscription access point to the Internet.
Newsgroups: comp.lang.c++
From: lenny@inmet.camb.inmet.com (Len Goodman)
Subject: Is "Classic Data Structures in C++" Still Available ??
Organization: Intermetrics Inc, Cambridge MA
Date: Wed, 2 Sep 1992 01:17:12 GMT

A few months ago, a message was posted giving the net address for a
"tex"-formatted copy of the book "Classic Data Structures in C++". 
Does anyone know if the book is still available by ftp, and what 
the net address of the site which has the "tex" files?? Thanks.
    -- Len Goodman
From: ark@alice.att.com (Andrew Koenig)
Newsgroups: comp.lang.c++
Subject: Re: Destruction of temporaries
Date: 1 Sep 92 12:51:55 GMT
Article-I.D.: alice.23599
Reply-To: ark@alice.UUCP ()
Organization: AT&T Bell Laboratories, Murray Hill NJ

In article <rmartin.715268992@thor> rmartin@thor.Rational.COM (Bob Martin) writes:

> These strategies should not supress the warnings.  ANY time an address
> or reference to a temporary is taken, whether is is via implicit
> conversion, or as the argument of a member function, a warning should
> be issued.  No exceptions.

> This will flag every instance where a long lived alias to a temporary
> could be created.

No, it will flag some instances.  For example:

	struct A {
		A& foo();
	};

	A a();

	main()
	{
		A& b = a().foo();
	}

Should this give a warning or not?  It is impossible to tell without seeing the
definition of A::foo.  For instance, it might be:

	A& A::foo() {
		static A aa;
		return aa;
	}

in which case there is no problem, or it might be

	A& A::foo() {
		return *this;
	}

in which case there is.  Without seeing it, the compiler can't tell.

But looking at A::foo without seeing main, it's impossible to tell either.
Returning *this from a member function is completely innocent unless the
member happens to be called on a temporary object.
-- 
				--Andrew Koenig
				  ark@europa.att.com