Reputation: 33617
A codebase I work with has historically tried--purposefully--to avoid dependencies on stdio.h creeping in. It has its own print formatting and mechanisms, and those are what's supposed to be used instead of printf etc.
But someone adds a dependency every so often that has to get noticed and taken out. So I tried to make an alarm for the easiest of cases:
#if !defined(NDEBUG)
void printf(float dont_link_with_stdio_h);
#endif
The gcc people seem to have been thinking along the lines of stopping easy errors too, because there's a helpful message if you do this...whether you've included <stdio.h>
or not.
conflicting types for built-in function 'printf'
There's a way to turn this warning off (-fno-builtin
). And there are all kinds of approaches that would do things like filter the symbol dump for things you don't want to be there...
But is there a trivially easy non-warning-causing (if you didn't include stdio.h) way to alert someone that they've introduced an unwanted printf usage?
Upvotes: 12
Views: 850
Reputation: 36617
I wouldn't touch the source files at all. I'd modify the build script. Much easier to maintain, and much easier to prevent people from circumventing the restriction (e.g. by changing the code which causes compilation to fail).
For example, in a makefile, assuming you have an all
target that build everything
all:
grep stdio *.h *.c
if ["$?" -eq 0 ]; then
echo "Do not use stdio. Contact Joe for info"; exit 2;
fi
<other stuff to do the build here>
You can also do it on particular targets. For example, if you have a target that compiles a .c file to produce a .o file, just check the .c file before compiling it.
%.o : %.c
grep stdio $<
if ["$?" -eq 0 ]; then
echo "Do not use stdio. Contact Joe for info"; exit 2;
fi
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
Your only problem now is what to do if you have someone who is determined to bypass your restriction (e.g. by #include "bypass.joe"
where bypass.joe
has an #include <stdio.h>
). For that, look up tools to generate dependencies (e.g. gcc -MM
, makedepend
, etc) and use that to set up a way to search all of the files your source files depend on. If someone is that determined, also set protections on your makefiles so only you can edit them.
EDIT: If you have a tool set up to generate a dependency file, simply search that file for stdio
. If any compilation unit, directly or indirectly, includes stdio.h
, then it will be listed in the dependency file.
Upvotes: 3
Reputation: 38228
You can redefine printf
to be some nasty value that will cause a compilation or linking error. For example:
#define printf do_not_include_stdio_h
#include <stdio.h>
int main(void) {
printf("Hello, world!\n");
return 0;
}
undefined reference to `do_not_include_stdio_h'
You can munge the macro if you want it to be an even more obscure name or include invalid symbols if you're worried that some poor soul will have defined do_not_include_stdio_h
.
You can set the macro definition in the compiler flags so you don't have to manually edit the file(s). For example:
gcc -Dprintf=do_not_include_stdio_h my_file.c
Upvotes: 6
Reputation: 34839
To prevent inclusion of <stdio.h>
, I would go with
#if !defined(NDEBUG)
#if defined(EOF)
#error Do not include stdio.h, contact Joe for more information
#endif
#endif
Upvotes: 2