On Sun, Nov 15, 2009 at 19:13, David Brownell <davi...@pacbell.net> wrote: > On Sunday 15 November 2009, Michael Bruck wrote: >> >>> The macro is right above the table. > > Yep. At least, *now* it's right above.
This is the original commit: http://openocd.git.sourceforge.net/git/gitweb.cgi?p=openocd/openocd;a=blob;f=src/target/arm11.c;h=11e376a6e6b935e9107f60c1c1d01721d0da924d > >> >> The problem with this sort of macros is that > > ... it doesn't really add anything. Even though > it *is* right above that table, you still have to > think more about it than when you see standard > initializer syntax (".field = value,"). The lines > above the top of the table are not necessarily on > the screen, or in your memory. It avoids redundant code and focuses the attention on the important parts. >> >> we have >> >> a dozen targets and having a dozen different >> >> macros gets a bit tedious. The arm11 macros >> >> does show that certain things are tedious in OpenOCD >> >> speak, but hopefully we can address those on >> >> in a more general fashion. >> > >> > This seems highly unlikely, quite a few contributions here lately >> > center around enforcing antiquated bloated syntax. > > Instead of "antiquated bloated" I'd say "standard and > universally understood". We're not exactly talking > about a COBOL level of verbosity here. ;) struct foo and foo_t are both universally understood. "struct foo" however clutters the code, especially in long function parameter lists, and distracts from the underlying algorithms/parameters. What you call "standard" is just other people's programming preferences. > Did you ever see the original Bourne shell sources? > The ones that abused CPP to make the language look > like Algol-60 instead of C? Now *that* was centered > around enforcing antiquated syntax ... Your patch is purely about enforcing arbitrary syntax rules and in the process adding redundant code that obscures what is going on. For example consider: ... ARM11_HANDLER(init), ARM11_HANDLER(foo), ARM11_HANDLER(bar), GENERIC_ARM_HANDLER(dog), ARM11_HANDLER(moo), ARM11_HANDLER(close), ... While not elegant it makes it immediately clear that dog is derived from the generic arm handler. On the other hand in the macro-free version it is far easier to overlook: .init = arm11_init, .foo = arm11_foo, .bar = arm11_bar, .dog = arm_dog, .moo = arm11_moo, .init = arm11_close, >> > The patch does not >> > improve legibility it merely reflects certain contributer's personal >> > distaste for macros. >> >> This should be contributors', plural is probably warranted here. > > It's also a fairly standard policy in most projects: > avoid syntactic sugar macros. To be used, they need > first to be learned ... and that's effort that could > be more usefully applied to other tasks. And to be > used, they also need to be maintained ... likewise. The reason why I did not plug arm11 into the existing arm infrastructure and why we implemented etm as a tcl script instead of using etm.c is because, beside being mostly undocumented, most of the openocd code in these areas is a programming hazard full of endless repetitive code that obscures the underlying algorithms. Reverse engineering what these functions do just costs too much time. Take for example: fields[0].tap = etm_reg->jtag_info->tap; fields[0].num_bits = 32; fields[0].out_value = reg->value; fields[0].in_value = NULL; fields[0].check_value = NULL; fields[0].check_mask = NULL; fields[1].tap = etm_reg->jtag_info->tap; fields[1].num_bits = 7; fields[1].out_value = malloc(1); buf_set_u32(fields[1].out_value, 0, 7, reg_addr); fields[1].in_value = NULL; fields[1].check_value = NULL; fields[1].check_mask = NULL; fields[2].tap = etm_reg->jtag_info->tap; fields[2].num_bits = 1; fields[2].out_value = malloc(1); buf_set_u32(fields[2].out_value, 0, 0, 0); fields[2].in_value = NULL; fields[2].check_value = NULL; fields[2].check_mask = NULL; This piece of digital diarrhea is no doubt "standard and universally understood" C code. Unfortunately it is also an obstacle when someone tries to read the surrounding algorithm. If that block would say: OUT_FIELD(fields[0], 32, reg->value); OUT_FIELD(fields[1], 7, reg_addr); OUT_FIELD(fields[2], 1, 0); it would be macros you might have to look up once when you deal with openocd for the first time, but that is a tiny price to pay for immediately seeing the relevant parts of the action. Btw. I added a small typo to the long version above that would not be detected by the compiler and is difficult to make with the macro version. Do you think someone would spot that when checking this in as a patch? And if it is not a typo but an obscure special case for a given CPU, would you, when inheriting that code for another CPU, notice a small difference that is buried under that pile of repetitive code that you skim over at best? Or to take the ARM11_HANDLER example, would you quickly spot the error if you forgot to switch arm_bar to arm11_bar when you replace the function with a more specialized version? The point is, the arm11 code doesn't use macros for fun, it uses them for clarity and to avoid trivial mistakes. And unlike the OUT_FIELD example it uses them only where functions are impractical or impossible. My opinion is that a general distaste for macros (or any C code that deviates from K&R) is not a good reason to override these design decisions. Michael _______________________________________________ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development