Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!swrinde!zaphod.mps.ohio-state.edu!uakari.primate.wisc.edu!ames!decwrl!ucbvax!ernie.Berkeley.EDU!jwl From: jwl@ernie.Berkeley.EDU (James Wilbur Lewis) Newsgroups: comp.lang.c Subject: Re: Personal dialects and C++ overloading Message-ID: <34102@ucbvax.BERKELEY.EDU> Date: 4 Feb 90 02:39:20 GMT Sender: usenet@ucbvax.BERKELEY.EDU Reply-To: jwl@ernie.Berkeley.EDU (James Wilbur Lewis) Organization: University of California, Berkeley Lines: 111 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