6 ms·
If you want to debug preprocessor-generated code, -gdwarf-4 -g3 usually does the trick with GCC and Clang. If it doesn't, you can just gcc -E it and run it thro
by PeCaN 11y ago
If you want to debug preprocessor-generated code, -gdwarf-4 -g3 usually does the trick with GCC and Clang. If it doesn't, you can just gcc -E it and run it through clang-format or something, and compile and debug the expanded version. It's really not a big deal. You can have a Makefile rule to do this automatically, for example https://github.com/alpha123/yu/blob/master/Makefile#L70-L103 https://github.com/alpha123/yu/blob/master/Makefile#L70-L103
Saying the C preprocessor can "inject bugs" and make code that "can't be easily traced" is deceptive and wrong. It is, for all intents and purposes, a solved problem. That Makefile rule could be 3x shorter if I didn't go for some extra niceties like not expanding system headers. (As usual, 20% of the result takes 80% of the work). The preprocessor doesn't "inject bugs" anyway, unless you write very careless macros. Modern C, with things like __typeof, _Generic, and GCC/Clang's statement expressions means your macros can be totally safe against overwriting variables, double-evaluation, type errors, and more. You can, of course, still do silly things, but C isn't about protecting the programmer anyway, and that's totally fine if you're prepared for it.
Perhaps in C++ the preprocessor is ‘pure evil’, but in C it's a very useful part of the language.
- emcrazyone 11y agoI work in the embedded space and use a compiler from Green Hills. The preprocessor in either C or C++ is evil for the simple matter you can't debug it when the thing you're debugging is in production, symbols are stripped, and the disassemble resembles nothing you can marry up to actual C or C++ code. In simple cases, maybe, but in not so simple cases it's just evil. A modern compiler will optimized out the global consts anyways too...
- kllrnohj 11y agoIf you have a modern compiler then it supports outputting the pre-processor result. If you have a modern toolchain stack unwinding is already friendly to macro expansion. A production build does not mean you don't have symbols, it just means you don't have symbols in the executable. Stash your build symbols somewhere so you can symbolize the stacks offline. Macros don't change this. They are consistent output for the same input. Macros are not evil. Abusable, yes, but they also solve various sets of problems just better than any other solution.
- emcrazyone 11y agoOutputting the pre-processor result is not that helpful, you're still stuck with deciphering things. macro expansion is useless, again, for same reason you can't marry it to actual code. If you can do this now, would be at most curious (not interested) as it's evil to begin with. A production build in the embedded world, typically means you don't have symbols. Often they are stripped to save space and unless you have a USB stick or something you carry with you with map files, you're still toast. And there are a whole host of other reasons why they are just pure evil: 1. Global scope only. 2. Unexpected results rather than error messages - ISO25259 won't even allow you to do this if that tells you anything. 3. Can't use sizeof 4. no type checking. Every compiler I've used, including GCC, won't warn about if an int is compared to unsigned. 5. can't take the address 6. worst, substituted value need not even be legal in the context the #define is created because it is evaluated at each point it is referenced allowing to another evil problem of being able to reference objects that are not declared yet. I could go no... and I haven't even touched on strings yet. with so many problems, I have a hard time justifying or championing their use.
- kllrnohj 11y agoThe vast, vast majority of your "evil" list is either just wrong or unrelated. I don't think you really know what macros are or how/when to use them.
- kstenerud 11y ago> 1. Global scope only. So are functions, by that rationale. If you want to control scope of variables, pass in macro parameters. > 2. Unexpected results rather than error messages When have min() or max() produced unexpected results rather than error messages? They're macros, you know. > Every compiler I've used, including GCC, won't warn about if an int is compared to unsigned. -Wconversion > 5. can't take the address You can't take the address of a struct definition or a typedef, either. Macros are not replacements for functions; they're code generators. > 6. worst, substituted value need not even be legal in the context the #define is created because it is evaluated at each point it is referenced allowing to another evil problem of being able to reference objects that are not declared yet. I don't even... You do know that, following the preprocessing phase, the compiler actually checks the generated code for legality, right? And since when is forward referencing evil?
- veli_joza 11y agoBit off topic, but I also work in embedded (automotive) with Green Hills compiler & Multi2000 debugger. After using GCC and GDB, Green Hills tools are so much inferior that it has become the biggest issue on project. On top of it all, they require constant(!) connection to license server and will throw annoying popups if being disconnected for few minutes. It's so frustrating to constantly being punished by DRM even if I'm paying customer. Sorry for rant, I just needed to vent a bit.
- emcrazyone 11y agooh, I so agree with you. Their tools do SUCK! I constant lose connectivity with their probes and their paid support is atrocious and they can't even answer simple questions about their own products. Horrible, horrible experience. If you can avoid Green Hills, take it from a 20 year veteran, you should do so!
- electroly 11y agoAt my last job we used the Green Hills MULTI toolchain as well. We had USB dongle licensing; no license server was needed, just the little USB stick. And yeah, I hated using it too. Awful stuff. We went to great lengths to allow a testing version of the firmware to be built using Visual C++ and executed locally, just so we could avoid using the Green Hills stuff whenever possible.