Nodes with unlimited children.

A

Ali Cehreli

Or one can declare a templated "smart pointer" class:

std::list<std::auto_ptr<Room> > roomPointerList

This is undefined behavior. std::auto_ptr cannot be used as a standard
container member because it doesn't have the copy semantics that the
standard containers require.

Ali
 
T

The Ghost In The Machine

In comp.os.linux.advocacy, Ali Cehreli
<[email protected]>
wrote
This is undefined behavior. std::auto_ptr cannot be used as a standard
container member because it doesn't have the copy semantics that the
standard containers require.

Ali

Ew. Thanks for the heads-up. :)

(You can tell how often I use it. :) )
 
J

Jeff Relf

Hi The Ghost In The Machine,

Even if your .CPP to .HTML syntax highlighter works,
I didn't like the .HTML code you showed me.

I know that mine works, and it works well,
and I prefer the HTML that it generates.

That C++ code of mine is at:

Ghost, I think you mostly write server-side Java,
so C++ is not really your forte... No shame in that.

As I think you suggested, my children are in a dynamic array,
So I might have to do a memmove() to insert nodes,
Or maybe use qsort() on it... I haven't gotten that far yet.

Here's an example of how my tree routines might be called.
( Correcting some mistakes I made earlier )

__stdcall WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{

// In the line below, the first call to Inc()
// creates one child ( * Lnk.P ) for Lnk
// ( Lnk is a global ) and returns a reference to it.
//
// That child ( * Lnk.P )
// is then is passed in a second call to InC(),
// which returns a reference to * Lnk.P->Lnk.P, a grandchild.
//
// There's no limit to the number of children per node.
//
// Afterwards Lnk.P->Lnk.P->Whatever
// is a valid int which is initialized to zero.

printf( "%d", Inc ( Inc ( Lnk ).Lnk ).Whatever );

// This prints all of Lnk's children.

LoopChildren printf( "%d, ", _Lnk->Whatever );

}

Here are the definitions...

// The - 1 below is so that I can pre-increment.

#define LoopChildren \
Link _Lnk = Lnk.B - 1 ; while ( ++ _Lnk < Lnk.P )

struct NodeT ;

typedef NodeT * Link ;

// B is the Beginning of an array of NodeT's.
// P is the Pointer to the NodeT being use.
// E is the End of an array NodeT's.
// Inc() allocates/increments P.

struct Lnk_T
{
Link B, P, E ;
};

struct NodeT
{
int Whatever ;
Lnk_T Lnk ;
};

Lnk_T Lnk ; // A global, so it's already initialized.

enum {
Sz_Node = sizeof NodeT
};

NodeT & Inc ( Lnk_T & Ln )
{
if ( Ln.E && ++ Ln.P < Ln.E )
return * Ln.P ;

// 4 nodes are created at a time, but this could be tweaked
// so that it grows by a certain percentage of Ln.P - Ln.B
int E = Ln.E - Ln.B + 4 ;
int P = Ln.P - Ln.B ;

Ln.B = ( Link ) realloc( Ln.B, E * Sz_Node );
Ln.E = Ln.B + E ;
Ln.P = Ln.B + P ;

memset( Ln.P, 0, ( Ln.E - Ln.P ) * Sz_Node );

return * Ln.P ;
}
 
J

Jeff Relf

Hi Karl Heinz Buchegger,

You think my C++ code would be easier to maintain
is I used more whitespace and longer identifiers ?

I don't agree at all.

You will never ever catch me telling someone that
his code is hard to maintain ( at least if I'm honest ).

I might well refuse to maintain someone's old code,
as I always prefer total rewrites.

Re: struct Lnk_T { Link B, P, E ; };

You commented: << Which only proves that
it is possible to write Fortran code in every language. >>

I actually own a 450 dollar copy of MS Fortran for Win98.
( From when I converted some Fortran code to C )

But I never used it, thank God... I refused to.

So I know what Fortran code ( and Fortran programmers )
look like ( with their big iron, IBM, and all that ).

I've seen those huge hard disk platters.

Hmm... Where they the forerunner to floppies ?
( Not counting tape, of course )
 
K

Kelsey Bjarnason

[snips]

struct Lnk_T { Link B, E, Room ; };
struct NodeT { int Whatever ; Lnk_T Lnk ; };

Lnk_T? NodeT? Consistency is a good thing in programming.
 
K

Kelsey Bjarnason

Hi Karl Heinz Buchegger,

You think my C++ code would be easier to maintain
is I used more whitespace and longer identifiers ?

If it were formatted for readability and used variables and other symbols
which themselves indicated their use, yes.
I might well refuse to maintain someone's old code,
as I always prefer total rewrites.

Not surprising, given your code. Most of us, however, don't see
reinventing the wheel as a good thing; if there's existing code which can
be modified to suit the task, rather than writing entirely new code, we do
it; it saves time, effort and bugs - the existing code is much more likely
to have been relatively debugged than the new code.

Writing unmaintainable code, as you do, does, indeed, make one want to
rewrite it.
 
J

Jeff Relf

Hi Kelsey Bjarnason,

Re: struct Lnk_T { Link B, E, Room ; };
struct NodeT { int Whatever ; Lnk_T Lnk ; };

You wrote: << Lnk_T ? NodeT ?
Consistency is a good thing in programming. >>

I'm currently favoring these two rules:
A. Place a capital T at the end of typedef identifiers.
B. If the T is preceded by a tall letter, such as a k,
then add an underscore in front of it.

But as I said before,
I sometimes like to change such rules
as it helps me review my code.

I'm now creating not only a forest of Usenet threads
but also a sorted array of Message-IDs,
linked to the nodes in that thread,
so that I can perform binary searches on them.

So I'm back to where I first started in this thread,
arrays of pointers to NodeT,
rather than arrays of NodeT.

struct NodeT ; typedef NodeT * Lnk_T ;

typedef Lnk_T * Lnk_Arr_T ;

typedef char * Line ; typedef Line * LineArr ;

struct NodeT { int LineArr Ln ; Lnk_Arr_T B, P, E ; };

NodeT Node ; // This is the forest of threads, a global.

In You said: <<
There are times and places for typedefs;
a simple pointer type isn't one of them -
it obscures details which don't benefit from being obscured,
without bringing in any additional clarity. >>

I might agree with you
if you were referring to some else's code,
but when it's me that wrote the code
I prefer see: Line P ; rather than: char * P ;

And it's me that has do code the some of a bitch, not you.

You mentioned the Direct Draw 7...
it works, and it works quite well...
and that's all I care about.

I use the high-precision timer, QueryPerformanceCounter(),
to ensure that I never draw more often than
once every fiftieth of a second.

That gives me virtually instant scrolling.
not a nanosecond of delay due to drawing.

I just set a variable if something needs to be drawn,
( such as a cursor movement )
and then I paint the entire window...

I works like a dream.

X's window ( my newsreader ) is a maximized using:
SystemParametersInfo( SPI_GETWORKAREA, 0, ( RECT * ) R, 0 );
so it allows for the taskbar, and it is high-res.

You mentioned my:
#define Eq ! strcmp
#define Eqi ! stricmp
#define EqN ! strncmp
#define EqiN ! strnicmp

Saying: if ( Eq( P, "Hello" ) || Eq( P, "Good-bye" ) )

just looks better than:
if ( ! strcmp( P, "Hello" ) || ! strcmp( P, "Good-bye" ) )

You disagree ? Who cares ?

As for :
#define Loop( N ) int J = -1, LLL = N ; while ( ++ J < LLL )

That's the best piece of code I ever wrote.
 
T

The Ghost In The Machine

In comp.os.linux.advocacy, Kelsey Bjarnason
<[email protected]>
wrote
If it were formatted for readability and used variables and other symbols
which themselves indicated their use, yes.


Not surprising, given your code. Most of us, however, don't see
reinventing the wheel as a good thing; if there's existing code which can
be modified to suit the task, rather than writing entirely new code, we do
it; it saves time, effort and bugs - the existing code is much more likely
to have been relatively debugged than the new code.

Writing unmaintainable code, as you do, does, indeed, make one want to
rewrite it.

I for one would be curious as to whether someone's developed
a tool that would allow for the management of unreadable C
code.

Something along the lines of Eclipse, perhaps?

Anyway, the capabilities that I might find useful are these:

[1] "De-macroization" of function calls and identifiers. Basically,
it would either expand by one level or down to standard macros.
More on "standard macros" later on.

[2] Replacement of local variable names. If I see a 'c', I can replace
it with 'local_speed_of_light'. (That's a bit contrived but you
get the idea.) No other instances of 'c' out of the scope would
be affected.

[3] Replacement of global variable names. This one's a bit trickier
and would require that the development environment know a lot
more about the system under development -- every module would
have to be looked at. One other possibility: conversion of a global
variable to a static scoped classfield name:

x => Y::z

and inclusion somewhere of:
class Y { public: static int z; }
int Y::z = 0;

Or even a non-static accessor function:

x => Y::singleton_y().z()
class Y { public: static Y & singleton_y(); int z(); }
Y & Y::singleton_y() { ... }
int Y::z() { ... }

[4] Elimination of unnecessary #includes, and proper guardbanding of
user #includes and certain system #includes.

[5] Identification of standard macros such as 'getchar', 'EOF', and
'FD_SET', so that they don't get de-macroized in [1]. Shadowing
of macros would be properly detected.

[6] Of course it should prettyprint. There are a few issues here, mostly
of the "which scheme did you like?" type.

[7] Auto-docstubbing. Basically, declarations of the type:

int x,y,z,w;

would be replaced by:

int x; // TODO: what is x?
int y; // TODO: what is y?
int z; // TODO: what is z?
int w; // TODO: what is w?

One could also extend parameter lists, either old- or new-style.

a(int b, int c) =>
a(
int b, // TODO: what is b?
int c // TODO: what is c?
)

Of course variable and parameter lists with existing documentation
would be unaffected.

[8] Something along the lines of javadoc or Cweb, for generation
of documentation from the codebase. Ideally, the reverse would
also be possible but most Marketing departments won't be
technical enough to get the formatting quite right. (It's an
interdepartmental negotiation process in any event.)

[9] If I need a system macro or function, the system would at my
behest include the relevant #include file, if it's not already there
(or #included by some other #include file I already have).
This could also be extended to include user-defined stuff
as well.

[10] All of this would be nicely visual. KDevelop isn't too bad as
a starting point, for example, though I can't say I like some
of Qt's hacks.

[11] Detection of loop-local variables, and the replacement of:

int i;

for(i = 0; ...) {
}

with

for(int i = 0; ...) {
}

if 'i' is used nowhere else in the module.

[12] A capability similar to [3] except for addition, renaming, and
possibly even deletion of base-level virtuals.

[13] Methods by which one can splice and merge class hierarchy,
by creating a new base or derived class and then moving methods
and fields around. The constructors and accessors would do the
right thing.

[14] A method by which one can move virtuals, leaving a "ghost"
(pure virtual) in the right place.

[15] A method by which one can replace pointer declarations with a
"smart pointer", and a simple template for declaring "smart pointers".
There are admittedly a few ugly issues here (my implementation
of "smart pointers" requires two friend declarations, for example,
and requires an extra int to manage the refcount).

[16] Individual, group, and company-wide policy declarations to manage
all this.
 
T

The Ghost In The Machine

In comp.os.linux.advocacy, Jeff Relf
<Jeff_Relf_@_NCPlus.NET.Invalid>
wrote
Hi The Ghost In The Machine,

Even if your .CPP to .HTML syntax highlighter works,
I didn't like the .HTML code you showed me.

Your perogative, of course.
I know that mine works, and it works well,
and I prefer the HTML that it generates.

That C++ code of mine is at:

Ghost, I think you mostly write server-side Java,
so C++ is not really your forte... No shame in that.

At least my C++ is readable. Also, I've worked with
C++ since my introduction thereto in the late 80's/
early 90's. I still remember assigning to "this" as
a tool -- which was thankfully removed later on -- and
the staged compile from C++ to C using AT&T's cfront, which
was also removed later on. GCC came later, and now --
finally -- GCC understands namespaces.

STL is one of C++'s prettier efforts, although I'm not
entirely certain as to the philosophy, which tries to
separate:

implementation
data store
and a third thing which I forget now, though it might be
something along the lines of collection type.

The same code, in particular, should work for a std::set as
for a std::list or a std::vector -- and, it turns out,
it does, if written properly.
As I think you suggested, my children are in a dynamic array,
So I might have to do a memmove() to insert nodes,
Or maybe use qsort() on it... I haven't gotten that far yet.

Gad, such ugly details for what should be a nice, abstract
collection.
Here's an example of how my tree routines might be called.
( Correcting some mistakes I made earlier )

__stdcall WinMain( HINSTANCE, HINSTANCE, LPSTR, int )

Ew, Windowsite. :)
{

// In the line below, the first call to Inc()
// creates one child ( * Lnk.P ) for Lnk
// ( Lnk is a global ) and returns a reference to it.
//
// That child ( * Lnk.P )
// is then is passed in a second call to InC(),
// which returns a reference to * Lnk.P->Lnk.P, a grandchild.
//
// There's no limit to the number of children per node.
//
// Afterwards Lnk.P->Lnk.P->Whatever
// is a valid int which is initialized to zero.

printf( "%d", Inc ( Inc ( Lnk ).Lnk ).Whatever );

// This prints all of Lnk's children.

LoopChildren printf( "%d, ", _Lnk->Whatever );

}

Here are the definitions...

// The - 1 below is so that I can pre-increment.

#define LoopChildren \
Link _Lnk = Lnk.B - 1 ; while ( ++ _Lnk < Lnk.P )

Now that's just absolutely dis-GUST-ing. Suppose, for
example, you had a collection of collections? (Rare,
but it happens.)

Also, you could just do

while(_Lnk < Lnk.P) _Lnk++;

though it depends on whether you've looked at the assembly
output or not to see which method's more efficient.

A good optimizing compiler won't care anyway.
struct NodeT ;

typedef NodeT * Link ;

// B is the Beginning of an array of NodeT's.
// P is the Pointer to the NodeT being use.
// E is the End of an array NodeT's.
// Inc() allocates/increments P.

struct Lnk_T
{
Link B, P, E ;
};

struct NodeT
{
int Whatever ;

Pointers don't fit in ints anymore. :)
Lnk_T Lnk ;
};

Lnk_T Lnk ; // A global, so it's already initialized.

enum {
Sz_Node = sizeof NodeT
};

NodeT & Inc ( Lnk_T & Ln )
{
if ( Ln.E && ++ Ln.P < Ln.E )
return * Ln.P ;

// 4 nodes are created at a time, but this could be tweaked
// so that it grows by a certain percentage of Ln.P - Ln.B
int E = Ln.E - Ln.B + 4 ;
int P = Ln.P - Ln.B ;

Ln.B = ( Link ) realloc( Ln.B, E * Sz_Node );
Ln.E = Ln.B + E ;
Ln.P = Ln.B + P ;

memset( Ln.P, 0, ( Ln.E - Ln.P ) * Sz_Node );

return * Ln.P ;
}

And suppose I want to cluster my allocations 8 to a page?
For that matter, how about allocating an entire page? Memory
faults are a problem.

(In STL such details are pushed to an Allocator or Allocation
sublayer -- I forget which. I rarely use it. realloc() is
a problem waiting to happen on C++ classes, if not used
properly.)
 
T

The Ghost In The Machine

In comp.os.linux.advocacy, Kelsey Bjarnason
<[email protected]>
wrote
[snips]

struct Lnk_T { Link B, E, Room ; };
struct NodeT { int Whatever ; Lnk_T Lnk ; };

Lnk_T? NodeT? Consistency is a good thing in programming.

Assumine anyone even wants to pursue this already-solved problem.
Herewith examples of processing things in STL.

The "explicit typedef/for loop" way.

#include <list>

class C { public: C() {...} ... };

typedef std::list<C> list_of_things_type;
list_of_things_type list_of_things;

void routine() {

/* ... */

for(list_of_things_type::const_iterator i = list_of_things.begin();
i != list_of_things.end(); i++)
{
const C & obj = *i;
/* ... obj ... */
}

Or, if one wants to,

#include <algorithm>
#include <list>

class C { public: C() {...} ... };

std::list<C> list_of_things;

void func(const C & obj)
{
/* ... */
}

class D { public: void operator()(C const & obj) { ... } };
D dobj;

void routine() {

/* ... */

std::for_each(list_of_things.begin(), list_of_things.end(), func);
std::for_each(list_of_things.begin(), list_of_things.end(), dobj);

}

which evokes memories of LISP's apply(), for those so inclined.

If one replaces std::list<> with std::vector<>, std::set<>,
or std::hashset<> -- the code changes are minimal, limited
only to the declaration. std::map<> and std::hashmap<>
require a little work, mostly because the iterator
returns a pair of items (key/value). But std::set<> takes
as one of its template arguments a comparison method, which
means that the collection can be in any order the programmer wants,
automatically maintained as objects are added or removed.

Compared to this level of elegance, Jeff's code is, in the
considered opinion of this particular C++ programmer,
swamp muck. :p~~~

Not that this is a perfect solution, mind you; there are some
constructs in C++/STL that are downright ugly. Try writing
the following loop using std::find(), for example.

typedef std::map<std::string, C, std::less<std::string> > things_map_type;
things_map_type things_map;

/* ... */

for(things_map_type::const_iterator i = things_map.begin();
i != things_map.end(); i++)
{
const C & key = (*i).first;
const C & val = (*i).second;
if(!val.isDesirable())
break;
}

The best I can do is something using std::unary_negate<> and _Select2nd,
and I'm not sure that's quite kosher -- or even right. Yuck.

But at least C++/STL can do it; in Java one would probably have to
leave the loop as is. (Java does offer Arrays.binarySearch()
and Collections.binarySearch(), but both assume already-sorted
collections (either an array or a list).)
 
J

Jeff Relf

Hi The Ghost In The Machine,

You wrote: <<
I for one would be curious as to
whether someone's developed a tool that would allow for
the management of unreadable C code. >>


Unreadable C code ?

Don't you mean code that you don't Want to read ?

You wrote: <<
Something along the lines of Eclipse, perhaps ? Anyway,
the capabilities that I might find useful are these:... >>

I know nothing about Eclipse,
but I am curious as to who exactly would want a machine
to control so many aspects of one's source code.

Certainly not a real programmer, I assume.

You wrote: << [ 16 ]
Individual, group, and company-wide policy declarations... >>

Shudder... I'll pass on that, thanks anyways.

Actually pounding out code is a piece of cake,
designing it is the main problem... as they say:
The Devil is in the details.

For my own review,
and for anyone else who might enjoy glancing at it ( ha ! ),
I've included some code snippets below,
describing my newsreader's threaded and unthreaded mode.

Why didn't I write this weeks ( months ) ago ?
Mostly because of my vast indecision...
I can't decide how I want the interface to look...
( and my mind wanders off too )

After spending many days thinking about it in these newsgroups
including several hours punching it in
( first one way, then the other ) ...

once I hit build,
it actually ran as designed, with only a few minor typos.

But that's the problem...
it's running as I designed it,
And I'm not sure what I want it to do.

For clarity ( ha ! ), some of the code is out of sequence.

Here are some globals:

Ln_T Ln ; // This holds the dynamic array of lines,
// i.e. the screen.

NodeT Forest, Flat ; // Threaded and unthreaded views.

// This is an abriviated list of headers.
// ( They are indexes for an array of lines )

enum { _Score, _Date, _Path, _Reader, _Name,
_XRefs, _Subj, _MID, _Par, _Par2, _Par3, _Par4, _Par5, _Lns };

Somwhere in WinMain()'s event loop...

// Deletes the old forest, and it's flat view.

DeC ( & Forest ); Zero( Forest );

free ( Flat.B ); Zero( Flat );

// Loops backwards though an array of lines
// containing a list of abriviated headers
// in the reverse order as that found on the server.
// ( Yes, that's a double reverse beause I store
// the headers in reverse order )

LoopR { Line Par = _Ln [ _Par ];

// Posts are assigned a single letter score,
// from 0-9, A-Z, a-Z

char & C = * _Ln [ _Score ] ;

// I get zero, replies to me are 1-5, based on proximity.

Loop ( 6 ) if ( EqN ( _Ln [ _MID + J ], "_Jeff", 5 ) ) {
C = '0' + J ; goto Done; }

if ( NID ("l7Um" ) || NID ( "pejU" ) ) C = 'A' ; else {
Line Pat = "server.com"; int PatL = strlen ( Pat );
Line B = _Ln [ _MID ], Cmp = strchr( B, 0 ) - PatL ;
if ( Cmp >= B && EqN ( Cmp, Pat, PatL ) ) C = 'B' ; else

// Titles starting without "Re: " get a C.

if ( ! EqN ( _Ln [ _Subj ], "Re: ", 4 ) ) C = 'C' ; else
C = 'N' ; } Done:

// Post has no parent, so it's at the top level.

if ( ! * Par ) AllocN( & Forest )

// Looks for the parents Message-ID in the unthreaded list.
// ( Which is just an array of links to the threaded list )

LoopC ( & Flat )
if ( Eq ( Par, ( * Arr )->Ln [ _MID ] ) ) break ;

// The parent was not found, so put it at the top level.

if ( Arr > Flat.P ) AllocN( & Forest )

// Make it * Arr's child.

AllocN( * Arr ) }

// This rolls back the array of lines,
// because they now reside only in the forest.

Ln.P = Ln.B + I_Cook - 1 ;

// This prints out the messsages in a threaded view.
// ( Much work must be done here )

PrnC( & Forest, 0 );

.......

DeC ( Lnk_T Lnk ) { if ( ! Lnk->B ) return ;
LoopC ( Lnk ) { Lnk_T P = * Arr ;

// Recursively deletes... how fun.

DeC ( P );

// Deletes the array of lines that contain
// the abreviated headers.

LineArr Ln = P->Ln - 1 ;
Loop( _Lns ) free ( * ++ Ln ); free ( P ); }

free ( Lnk->B ); }


PrnC ( Lnk_T Lnk, int Lv ) { if ( ! Lnk->B ) return ;
LoopCR ( Lnk ) { Lnk_T P = * Arr ;

// Prints recursively.

PrnC ( P, Lv + 1 ); LineArr & Ln = P->Ln ;

// Dumps the contents of a node ( a message ).

Sh( "%s %d %s, %s, %s, %s\n %s\n %s\n %s",
Ln [ _Score ], Lv, Ln [ _Date ], Ln [ _Path ],
Ln [ _Reader ], Ln [ _Name ], Ln [ _XRefs ],
Ln [ _MID ], Ln [ _Subj ] ); } }


// THis grows a parent's list of children ( unlimited ).

Lnk_T & Inc ( Lnk_T Lnk ) {

// No need to allocate a new pointer

if ( Lnk->B && ++ Lnk->P < Lnk->E ) return * Lnk->P ;

// Give me 40 new pointers

int E = Lnk->E - Lnk->B + 40, P = Lnk->P - Lnk->B ;
Lnk->B = ( Lnk_Arr_T ) realloc( Lnk->B, E * Sz_Ptr );

// Initialize the newest pointers

Lnk->E = Lnk->B + E ; Lnk->P = Lnk->B + P ;
memset( Lnk->P, 0, ( Lnk->E - Lnk->P ) * Sz_Ptr );

return * Lnk->P ; }

.....
typedef char * Line ;

typedef Line * LineArr ;

struct Ln_T { LineArr B, P, E ; };

struct NodeT ; typedef NodeT * Lnk_T ;

typedef Lnk_T * Lnk_Arr_T ;

struct NodeT { LineArr Ln ; Lnk_Arr_T B, P, E ; };

#define Zero( X ) memset( & X, 0, sizeof X );

#define AllocN( Lnk ) { Lnk_T & P = Inc ( Lnk ); \
P = ( Lnk_T ) malloc( sizeof NodeT ); rv = _Lns * Sz_Ptr ; \
memmove( P->Ln = ( LineArr ) malloc( rv ), _Ln, rv ); \
memset( _Ln, 0, rv ); \
P->B = P->P = P->E = 0 ; Inc ( & Flat ) = P ; continue; }

#define Loop( N ) int J = -1, LLL = N ; while ( ++ J < LLL )

#define LoopR LineArr B = Ln.B + I_Cook - 1, \
_Ln = ! Ln.B ? B : Ln.P + 1 ; while ( ( _Ln -= _Lns ) > B )

#define LoopC( Lnk ) Lnk_T _Lnk = Lnk ; \
Lnk_Arr_T E = _Lnk->P + 1, \
Arr = ! _Lnk->B ? E : _Lnk->B - 1 ; while ( ++ Arr < E )

#define LoopCR( Lnk ) Lnk_T _Lnk = Lnk ; \
Lnk_Arr_T B = _Lnk->B - 1, \
Arr = ! _Lnk->B ? B : _Lnk->P + 1 ; while ( -- Arr > B )
 
J

Jeff Relf

Hi Kelsey Bjarnason,

Re:
#define Loop( N ) int J = -1, LLL = N ; while ( ++ J < LLL )

You commented: << Marvellous; symbol clashes,
just because you use this macro twice in the same scope.
Talk about badly-written. >>

You're worried about compilation errors ?

Real programmers are Never concerned about that.

This code compiles, and it does just what I would expect:

FuBar () { int X = -1, Y = -1 ;

Loop ( 6 ) { ++ X ; Loop ( 7 ) ++ Y ; }

// Prints: 5 and 6

printf ( " %d and %d ", X, Y ); }

You wrote: <<
Do us a favour: never, ever, post your code anywhere again.
Some poor unsuspecting soul might think
you know what you're doing and try to mimic you. >>

Call me an ignorant idiot ( yet again ),
but I, for one, don't think you're a Real programmer.

I started coding HP-67 calculators
( with the magnetic strips ) back in 1976.

Programming has been my sole profession since the start of 1982,
and, as you can see, I'm building my own newsreader...

So it's also my hobby.

I wrote: << I know nothing about Eclipse,
but I am curious as to who exactly would want a machine
to control so many aspects of one's source code. >>

And you replied: << To automate converting code such as yours
into something sane. >>

Now I know you're not a programmer,
changing the whitespace, macros and such
is a really good way to familiarize yourself with the code.

That's why I sometimes do that to my own code.
( e.g. Stuff I wrote 12 years ago )
 
P

Phlip

Jeff said:
Hi Kelsey Bjarnason,

Re:
#define Loop( N ) int J = -1, LLL = N ; while ( ++ J < LLL )

You commented: << Marvellous; symbol clashes,
just because you use this macro twice in the same scope.
Talk about badly-written. >>

You're worried about compilation errors ?

Real programmers are Never concerned about that.

Real programmers don't piss their colleagues off. They write clear, simple,
robust, and easily-changed code. This helps keep their colleagues in the ...
loop.
 
J

Jeff Relf

Hi The Ghost In The Machine,

You showed something like this:

for ( list_of_things_type::const_iterator
i = list_of_things.begin();
i != list_of_things.end();
i ++ )
{ const C & obj = *i;
/* ... obj ... */
}

And then you commented: <<
Compared to this level of elegance, Jeff's code is,
in the considered opinion of this particular C++ programmer,
swamp muck. :p~~~ >>

Are you really a C++ programmer ? I don't think so.

Java maybe, server side perhaps,
but you're not a serious Win XP C++ programmer.

You want to make comparisons ?

This is how I loop through a list of unthread Usenet messages:
( From )

LoopC ( & Flat )
if ( Eq ( Par, ( * Arr )->Ln [ _MID ] ) ) break ;

This is how I delete a forest of threaded messages:

DeC ( Lnk_T Lnk ) { if ( ! Lnk->B ) return ;
LoopC ( Lnk ) { Lnk_T P = * Arr ;

// Recursively deletes... how fun.

DeC ( P );

// Deletes the array of lines that contain
// the abbreviated headers.

LineArr Ln = P->Ln - 1 ;
Loop( _Lns ) free ( * ++ Ln ); free ( P ); }

free ( Lnk->B ); }

I'm looking at your way... and my way...

I'm comparing the two, and I'm very much preferring my way.

By the way...

People are Still inventing wheels... as they well should.

It's called: A better tire.
 
K

Karl Heinz Buchegger

Jeff said:
Hi The Ghost In The Machine,

_____________________
/| /| | |
||__|| | Please do not |
/ O O\__ | feed the |
/ \ | Trolls |
/ \ \|_____________________|
/ _ \ \ ||
/ |\____\ \ ||
/ | | | |\____/ ||
/ \|_|_|/ | _||
/ / \ |____| ||
/ | | | --|
| | | |____ --|
* _ | |_|_|_| | \-/
*-- _--\ _ \ | ||
/ _ \\ | / `
* / \_ /- | | |
* ___ c_c_c_C/ \C_c_c_c____________
 
J

Jeff Relf

Hi The Ghost In The Machine,

Re:
#define LoopChildren \
Link _Lnk = Lnk.B - 1 ; while ( ++ _Lnk < Lnk.P )

You wrote: << Also, you could just do

while(_Lnk < Lnk.P) _Lnk++;

though it depends on whether you've looked at the assembly
output or not to see which method's more efficient. >>

No, you missed one of the main reasons for LoopChildren:

It pre-increments. ( Hence the initial -1 )

Your alternatives, mentioned in your other posts,
all used post-increments, which I don't like.

The other reason for defining something like LoopChildren
is how clean it makes the code look.

For an example of that, see my other post:

You mentioned:
" Pointers don't fit in ints anymore. :) "

I don't ever do that, never did.

All the code that I showed used:

typedef char * Line ;

enum { Sz_Ptr = sizeof Line };

Slap that on a 64-bit computer, and is still works...

I know because I've done this before.

Re: Memory faults,

You asked: <<
And suppose I want to cluster my allocations 8 to a page ?
For that matter, how about allocating an entire page ?
Memory faults are a problem. >>
...
<< ...realloc() is a problem waiting to happen on C++ classes,
if not used properly. >>

My memory usage is not very taxing at all.

I'm not writing a fault-tolerant server
that supports terabytes of data
and has to remain up for months on end.

At any rate,
I'm no longer using the code you were referring to.

Now I only allocate dynamic arrays of pointers,
not nodes...

But even that node that you were referring to was tiny,
just an int and three pointers,
it was not designed to be large.
 
J

Jeff Relf

Hi Karl Heinz Buchegger,

Re: The Ghost In The Machine and me,

You wrote: <<
_____________________
/| /| | |
||__|| | Please do not |
/ O O\__ | feed the |
/ \ | Trolls |
/ \ \|_____________________|
/ _ \ \ ||
/ |\____\ \ ||
/ | | | |\____/ ||
/ \|_|_|/ | _||
/ / \ |____| ||
/ | | | --|
| | | |____ --|
* _ | |_|_|_| | \-/
*-- _--\ _ \ | ||
/ _ \\ | / `
* / \_ /- | | |
* ___ c_c_c_C/ \C_c_c_c____________

At least we're talking abut C++, doesn't that count ?

I don't think the Ghost is a troll,
I just think he has a different point of view from me.

A lot of people have scored me down too,
but that's fine with me...

I'm not entering anyone's popularity contest.

It's even possible that
The Ghost and I could come to a understanding.

There's so much miscommunication on Usenet...

Why not try to resolve some of it ?
 
T

The Ghost In The Machine

In comp.os.linux.advocacy, Jeff Relf
<Jeff_Relf_@_NCPlus.NET.Invalid>
wrote
Hi Kelsey Bjarnason,

Re:
#define Loop( N ) int J = -1, LLL = N ; while ( ++ J < LLL )

You commented: << Marvellous; symbol clashes,
just because you use this macro twice in the same scope.
Talk about badly-written. >>

You're worried about compilation errors ?

Real programmers are Never concerned about that.

This code compiles, and it does just what I would expect:

FuBar () { int X = -1, Y = -1 ;

Loop ( 6 ) { ++ X ; Loop ( 7 ) ++ Y ; }

// Prints: 5 and 6

printf ( " %d and %d ", X, Y ); }

Bleah.

Maybe what *you* expect. However, if one were to try to
convert it into a more elegant version of C++, inner loops
and all:

#include <stdio.h>
int main(int, char **)
{
int x = -1;
int y = -1;

for(int i = 0; i < 6; i++)
{
x++;
for(int j = 0; j < 7; j++)
y++;
}

printf("%d %d\n", x,y);
}

the results would be quite different -- and in fact
you've posted a bug -- a bad comment, for the most part.

Unless you meant

{ Loop (6) { ++X; } } { Loop (7) { ++Y; } }

which is what would be required to avoid naming collisions.

(The results I get are 5 and 41, before and after conversion.
This is regardless of whether I use 'i' or 'j' as the inner
variable, which shadows the outer one.)
You wrote: <<
Do us a favour: never, ever, post your code anywhere again.
Some poor unsuspecting soul might think
you know what you're doing and try to mimic you. >>

Call me an ignorant idiot ( yet again ),
but I, for one, don't think you're a Real programmer.

"Real" is a weird way of putting it.
I started coding HP-67 calculators
( with the magnetic strips ) back in 1976.

I started with a Wang, perhaps, back in '74 or thereabouts.
So there. :p
Programming has been my sole profession since the start of 1982,
and, as you can see, I'm building my own newsreader...

I've done RFC977 work. It's rather interesting, actually.

(No, you don't really want to know why. Suffice it to say
it was a phase many young males go through.)
So it's also my hobby.

I wrote: << I know nothing about Eclipse,
but I am curious as to who exactly would want a machine
to control so many aspects of one's source code. >>

And you replied: << To automate converting code such as yours
into something sane. >>

Now I know you're not a programmer,
changing the whitespace, macros and such
is a really good way to familiarize yourself with the code.

That's why I sometimes do that to my own code.
( e.g. Stuff I wrote 12 years ago )

I'm surprised you can read that gunk.
 
T

The Ghost In The Machine

In comp.os.linux.advocacy, Jeff Relf
<Jeff_Relf_@_NCPlus.NET.Invalid>
wrote
Hi The Ghost In The Machine,

Re:
#define LoopChildren \
Link _Lnk = Lnk.B - 1 ; while ( ++ _Lnk < Lnk.P )

You wrote: << Also, you could just do

while(_Lnk < Lnk.P) _Lnk++;

though it depends on whether you've looked at the assembly
output or not to see which method's more efficient. >>

No, you missed one of the main reasons for LoopChildren:

It pre-increments. ( Hence the initial -1 )

Your alternatives, mentioned in your other posts,
all used post-increments, which I don't like.

Your perogative. Personally, I think of preincr and postincr
as where one puts the 'INC Rx' instruction (or perhaps the
'INC memaddr' instruction, depending on compiler sophistication).

I write

for(int i = 0; i < n; i++)

but others might write

for(int i = 1; i <= n; ++i)

which works equally well except for the one-off.
The other reason for defining something like LoopChildren
is how clean it makes the code look.

Noooooo comment!
For an example of that, see my other post:

You mentioned:
" Pointers don't fit in ints anymore. :) "

I don't ever do that, never did.
Good.


All the code that I showed used:

typedef char * Line ;

enum { Sz_Ptr = sizeof Line };

Slap that on a 64-bit computer, and is still works...

I know because I've done this before.

Re: Memory faults,

You asked: <<
And suppose I want to cluster my allocations 8 to a page ?
For that matter, how about allocating an entire page ?
Memory faults are a problem. >>
...
<< ...realloc() is a problem waiting to happen on C++ classes,
if not used properly. >>

My memory usage is not very taxing at all.

No, but suppose you had N different listtypes?

Also, on an overloaded system, you'll feel it; a cheapie
page fault takes on the order of a few hundreds of nanoseconds,
but a pricey one will take a few milliseconds, as it reads
from swap.
I'm not writing a fault-tolerant server
that supports terabytes of data
and has to remain up for months on end.

Perhaps you should. :)
 
T

The Ghost In The Machine

In comp.os.linux.advocacy, Karl Heinz Buchegger
<[email protected]>
wrote
_____________________
/| /| | |
||__|| | Please do not |
/ O O\__ | feed the |
/ \ | Trolls |
/ \ \|_____________________|
/ _ \ \ ||
/ |\____\ \ ||
/ | | | |\____/ ||
/ \|_|_|/ | _||
/ / \ |____| ||
/ | | | --|
| | | |____ --|
* _ | |_|_|_| | \-/
*-- _--\ _ \ | ||
/ _ \\ | / `
* / \_ /- | | |
* ___ c_c_c_C/ \C_c_c_c____________

Hmph. Well, if you insist. :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
SterlingLa
Top