Personal dialects and C++ overloading

James Wilbur Lewis jwl at ernie.Berkeley.EDU
Sun Feb 4 13:39:20 AEST 1990


Ulrich Ruede writes:

-Well, knowing that the following program has to do with a graph (with
-attributed nodes and edges) would you prefer to see an initialization
-like
-
-	FOR_ALL_NODES_OF(a_mesh, this_node)
-		FOR_ALL_EDGES_OF(this_node, this_edge)
-			this_edge->component= 0;
-		END_ALL_EDGES
-	END_ALL_NODES
-
-or rather
-
-	{	
-		Node_Ptr this_node;
-		for(this_node= (a_mesh)->grd; (this_node) != NULL; (this_node)= (this_node)->next){
-			{ register Edge_Ptr	this_edge= (this_node)->c,
-			_end= (this_edge)+((this_node)->num_edges);
-			for(; (this_edge)<_end; (this_edge)++){
-				this_edge->component= 0;
-
-			}
-		}
-	}
-	}
-
-This has been produced by cb on the expanded result.

You've stacked the deck in favor of your macros by showing a fragment
of gross, badly-formatted machine-generated code.  I'd much prefer to see
something like this:

zero_components(a_mesh)
A_MESH_TYPE a_mesh;
{
  Node_Ptr this_node;
  register Edge_Ptr this_edge, end;

  for( this_node = a_mesh->grd;  this_node != NULL; this_node = this_node->next)
  {
     end = this_edge + this_node->num_edges;
     for(this_edge = this_node->c; this_edge < end; this_edge++)
     {
         this_edge->component = 0;
     }
  }
}

I notice that to "macroize" your operation, you had to introduce an extra
parameter into each macro (this_node and this_edge, respectively) to get the 
temp variables defined correctly.  And you rely on using an underscore to hide 
another temp variable from the macro user.  There is also the problem of 
"this_node" being evaluated multiply within the inner macro -- I pity 
the fool who writes FOR_ALL_EDGES_OF(this_node++,this_edge) !

-The macros enable me to define the data structures and the access to
-these structures together, as one module. If I don't use macros, the
-information how to access all nodes of the graph is dispersed throughout
-the program. 

There is almost always a better way to do this without resorting to the
preprocessor.  The operation above, "do something" to each edge of a
graph, probably *is* a common operation for you.  It shouldn't be too hard
to write that as a function instead of a set of macros -- perhaps you could
pass a function pointer to your routine which would specify the operation
to perform on each edge or node.  Or if the function call overhead in the inner loop bothers you, you could pass some sort of function code to the
routine and have a switch statement inside the loop to select from a
(hopefully small) set of operations.  

Once you get the operation in the form of a function call,  feel
free to define any macros you like to invoke it.  I won't care because
syntactically, it still looks like a function call, and my tools that
know C's syntax won't get confused by it.  And the specialized control
structure is still localized in one place, so you can modify it easily
without rewriting the rest of your code.

-I am using m4, so everyone who prefers the expanded result, can easily
-get it with all symbolic constants still in symbolic form.

Everyone who has access to m4, that is....tough darts if you're porting
it to VMESS or Mess-DOS! :-)

There are two related attributes of "well-writtten" programs that I'm trying 
to get across in this thread.  Programs should be written in such a way that
future maintainers can easily use whatever tools they might have at their
disposal.  (Specifically, since many interesting tools need to parse
your code, you should avoid macros that would choke a C parser.)  Your
coding style shouldn't force future maintainers to use any particular tool to 
make sense of it.  Don't assume that every programmer who will encounter your 
code has access to m4, or even the preprocessor!  All the world isn't a UNIX
box! 

-I also think that changing the syntax of a language is not a bad thing by
-itself. If you write a function, you have also changed the syntax
-of the language by introducing a new terminal symbol at the expression
-level. 

Not in any C grammar I've ever seen. 

Now if you want to talk about typedefs, that's another story!  

-It would still be better if these capabiltities [abstracting control 
-structures, etc. -jwl] were built into some language
-(without sacrificing performance).

I think inline functions would be good for that.  Too bad they're not
standard C!

-- Jim Lewis
   U.C. Berkeley



More information about the Comp.lang.c mailing list