Table Of Contents:
- #defined function-names after function-definitions (confusing)
- DO NOT TRUST: that there will be warnings/errors for uninitialized variables!!!
- (gnu make) Makefile Recursive inclusion follies (6-17-15)
- (gnu make) makefile auto-creation follies (6-17-15)
- (xc32-gcc, plausibly others?) escaping command-line quotes, etc. (7-14-15)
- function-like macros with/without return-values (7-16-15)
- TODOs and Qs (Latest: 1-29-16)
- Code-Size reduction ideas... check out #limited-code hacks/tips (added 11-26-16)
- I HAVE NOT been keeping this ToC up to date... check out the logs!
OTHER REFERENCES:
- computed-gotos, more efficient state-machines than using switch() ( @Analog Two's #reprint: modern printf )
1. #defined function-names after function-definitions
Thanks to @LazyHD for the reminder: This is generally considered BAD PRACTICE. But there may be times when you'll come across it's having-been-done (and most-likely by mistake!) and then it will be quite confusing.
(See his comment, below. But, briefly, #define's should be CAPITALIZED to avoid such confusion.)
#include <stdio.h>
//Uncomment one of the '#define function' lines to see what I'm sayin'
//Uncommenting this one results in an error...
//#define function() printf("running '#define function()'\n")
//And of course, disabling both #defines, results in this being called.,,
void function(void)
{
printf("running actual 'void function(void)'\n");
}
//Uncommenting this one results in no errors/warnings
// and *this* is called, not the actual function.
#define function() printf("running '#define function()'\n")
int main(void)
{
function();
}
This can be royally confusing... and SHOULD NOT BE DONE INTENTIONALLY.
Say you've a function between 'void function(void)' and the second '#define function()' which happens to call function()... it'll call the actual function, but main will call the #define... right? I dunno, it's risky-business. DON'T DO THIS. More-complicated programs, however, might just cause something like this, most-likely by mistake, e.g. through #if statements...
2. DO NOT TRUST: that there will be warnings/errors for uninitialized variables!!!
GCC: This one has bit me in the butt so many times...
int function(int b)
{
int a;
if(b==3)
a=3;
return a;
}
CLEARLY: a will only be assigned a value IF b==3!CLEARLY: "-Wuninitialized" and "-Werror=uninitialized" is designed *exactly* for the purpose of noting when a variable like int a; could be used without being assigned a value! GCC WILL NOT catch this case... at least with the versions I've used. You WILL NOT receive a warning, nor error, in this case! And, allegedly, there's no intention to fix this glitch.
There's a good discussion on it HERE.
3. (gnu make) Makefile Recursive Inclusion Follies
(initially poorly-titled: 'include $(INCLUDABLES)' wherein those 'INCLUDABLES' modify the variable 'INCLUDABLES')
Say you have a bunch of makefile 'snippets' you'd like included in a makefile.
makefile:
INCLUDABLES += inc1.mk
INCLUDABLES += inc2.mk
include $(INCLUDABLES)
INCLUDABLES += inc1a.mk
The end-result appears clear, at least on my system...
My search-fu is failing me. is this result expected/able to go cross-platform? cross-makes?
The end-result, on my system, is that apparently the call to 'include $(INCLUDABLES)' works with the variable 'INCLUDABLES' AS IT EXISTED when the 'call was placed'
So, inc1a.mk is never included.
(This goes against my [utter-lack-of-]understanding of make's "multipass technique", but goes completely in favor of my having an utter-lack-of-understanding of it, in the first place ;)
Thoughts?
4. (gnu make) makefile auto-creation follies
It's possible to have 'make' auto-create files it wishes to include...
e.g.
makefile:
include includeMe.mk
...if the file 'ncludeMe.mk' doesn't exist, 'make' can try to auto-create it based on a rule...
makefile continued:
# Rules:
#Default ('make')
all:
@echo "'make [all]'"
#Missing makefile snippet:
%.mk:
@echo "creating missing makefile snippet"
@touch $@"
Cool.
Now... what...
Read more »
Indeed, I was taught the same practice... Thanks for the reminder, I'll put a note of this in there!