Disable printf

R

RedDevilDan

I am working on a Memory Footprint Reduction project. I came across an
idea to disable all printf statements so that less memory is required.
In addition, when there is no single printf statement, the printf
library will not be linked, so it further reduces the executable size.
Is there an easy way to disable printf in a large project? In my
project, we have thousands of C & C++ files. They don't have a common
included common header. Otherwise, I can do a #define printf(x) in the
common header. I am using GNU GCC compiler and run the program in both
Linux and VxWorks platform.

Any of you have a suggestion on disabling all printf statements?

I also think about to add a common header file into the whole project.
However, I would need to put a #include "common.h" line into each c
file. It's gonna take a while to do that. Is there any way to insert
the line automatically into each c file?
 
W

William Hughes

RedDevilDan said:
I am working on a Memory Footprint Reduction project. I came across an
idea to disable all printf statements so that less memory is required.
In addition, when there is no single printf statement, the printf
library will not be linked, so it further reduces the executable size.
Is there an easy way to disable printf in a large project? In my
project, we have thousands of C & C++ files. They don't have a common
included common header. Otherwise, I can do a #define printf(x) in the
common header. I am using GNU GCC compiler and run the program in both
Linux and VxWorks platform.

Any of you have a suggestion on disabling all printf statements?

I also think about to add a common header file into the whole project.
However, I would need to put a #include "common.h" line into each c
file. It's gonna take a while to do that. Is there any way to insert
the line automatically into each c file?


This is of course about tool sets, not about the C language.

<OT>

Some random ideas.

You might be able to use gcc's -D'name(args..)=definition' option.
Depending on how things are arranged you might be able to
alias gcc or you may have to play around a blit with "PATH" and
the names of binary executables.

You could use your favourite scripting language to
insert the line #include "common.h" at the start of any file
ending ".c" or "cpp". Or you could compile generic.c by compiling
a file containing

#include "common.h"
#include "generic.c"

Again, you should be able to wrap this in a script, call it gcc, change
the PATH variable so that your gcc is called first and link
actual_gcc to /usr/bin/gcc and call actual_gcc from within the srcipt.
Then when the makefiles call gcc, they will get your version

</OT>
- William Hughes
 
R

RedDevilDan

Thanks for the reply at first.

I tried the gcc -D "printf(x)=" way. However, it complains about the
printf(x) at the stdio.h, "/usr/include/stdio.h:329:58: macro "printf"
passed 2 arguments, but takes just 1"
I guess the gcc doesn't know how to handle the std c lib if you
redefine printf

I like the idea of putting #include "common.h" line into each c or cpp
files. Do you know how? What kind of script can do this?

Thanks
 
K

Keith Thompson

RedDevilDan said:
Thanks for the reply at first.

I tried the gcc -D "printf(x)=" way. However, it complains about the
printf(x) at the stdio.h, "/usr/include/stdio.h:329:58: macro "printf"
passed 2 arguments, but takes just 1"
I guess the gcc doesn't know how to handle the std c lib if you
redefine printf

I like the idea of putting #include "common.h" line into each c or cpp
files. Do you know how? What kind of script can do this?

Please don't top-post. Read the following:
http://www.caliburn.nl/topposting.html
http://www.cpax.org.uk/prg/writings/topposting.php

I'm sure you can use some kind of script to add #include "common.h" to
each of your source files, but that's a question for a different
newsgroup. If you're on a Unix-like system, try comp.unix.shell or
comp.unix.programmer.
 
E

Eric Sosman

RedDevilDan said:
I am working on a Memory Footprint Reduction project. I came across an
idea to disable all printf statements so that less memory is required.
In addition, when there is no single printf statement, the printf
library will not be linked, so it further reduces the executable size.
Is there an easy way to disable printf in a large project? In my
project, we have thousands of C & C++ files. They don't have a common
included common header. Otherwise, I can do a #define printf(x) in the
common header. I am using GNU GCC compiler and run the program in both
Linux and VxWorks platform.

Any of you have a suggestion on disabling all printf statements?

I also think about to add a common header file into the whole project.
However, I would need to put a #include "common.h" line into each c
file. It's gonna take a while to do that. Is there any way to insert
the line automatically into each c file?

See William Hughes' reply for some ideas about introducing
a #define to "spike" printf. You might also want to spike the
related functions fprintf, sprintf, vprintf, vfprintf, vsprintf,
and possibly the scanf family as well.

But since you have "thousands of C & C++ files," it seems
doubtful that eliminating these parts of the library will make
a meaningful difference. It might, of course, and there are
always those cases where shrinking the program by twenty-seven
bytes means you don't need to buy another megabyte of memory.
But in all those "thousands" of other files, I sort of suspect
that you're likely to find other and better opportunities to
save. It's a fine thing to clear the bottle caps off the beach,
but doing something about the whale carcases comes first.

Another thing to note is that on many platforms, eliminating
references to a library function will shrink the program by a
grand total of zero bytes. Some systems (and I believe Linux is
among them) attach the entire Standard library to the program as
one indivisible unit, even if you use only strlen() and exit().
On these systems you'll get the whole library or none, and there
are no half-measures. (Well, maybe one half-measure: Some systems
divide the Standard library into a "core" portion and a "math"
portion, and if you never use sqrt() and sin() and so on you may
escape the burden of including the "math" part. But it's very
likely that you'll be unable to pick and choose: If you use so
much as malloc(), you'll probably get printf() anyhow, even if
you didn't ask for it.)

One space-saving suggestion: Try different optimization
levels on the compiler, if it offers them. Minimally optimized
code tends to be largish (it includes a lot of extraneous loads
and stores), and extravagantly optimized code also tends to be
largish (it unrolls loops and in-lines function bodies). You may
find that there's an in-between point that minimizes code size --
of course, you'll also need to balance this against execution
speed.
 
W

William Hughes

RedDevilDan said:
Thanks for the reply at first.

I tried the gcc -D "printf(x)=" way. However, it complains about the
printf(x) at the stdio.h, "/usr/include/stdio.h:329:58: macro "printf"
passed 2 arguments, but takes just 1"
I guess the gcc doesn't know how to handle the std c lib if you
redefine printf

Probably no. More likely the problem is that printf is a variadic
function
(takes a varying number of arguments) so you need to
replace it a variadic macro. Such macros do not exist
is C90, but they do exists in C99 and as a gcc extension. You
need something like

-D "printf(x,...)="
I like the idea of putting #include "common.h" line into each c or cpp
files. Do you know how? What kind of script can do this?

Just about any. If you don't have a favourite scripting language,
then this is as good a time as any to learn one. I would do this
sort of thing in Python (much more than "just" a scripting
language, but a good choice nonetheless), but there are many
alternatives
(for Unix) bash and csh shells scripts, Perl, ... Details are
very off topic here.

For details on aliasing and/or playing games with paths and filenames
try asking in comp.unix.programmer

But, as Eric Sosman pointed out, getting rid of printf might have
little to do with solving your problem. (Have you tried passing
-Os to gcc? ) Before you spend much effort on this at least
check a simple example to see if removing printf makes enough
of a difference to be worth doing.

- William Hughes
 
M

MQ

Eric said:
Another thing to note is that on many platforms, eliminating
references to a library function will shrink the program by a
grand total of zero bytes.

AFAIK, most applications on Linux load the C library as a shared
dynamic library, which is mapped into the processes application space
when the application requires it. In other words, the C library is
loaded once and is shared by all applications. Not only would you have
to remove the references to the C library from your application, but
ensure that every application running on the system does not use the C
library. If just one application uses it, then the benefit of doing
this is non-existent.

MQ
 
J

jaysome

I am working on a Memory Footprint Reduction project. I came across an
idea to disable all printf statements so that less memory is required.
In addition, when there is no single printf statement, the printf
library will not be linked, so it further reduces the executable size.
Is there an easy way to disable printf in a large project? In my
project, we have thousands of C & C++ files. They don't have a common
included common header. Otherwise, I can do a #define printf(x) in the
common header. I am using GNU GCC compiler and run the program in both
Linux and VxWorks platform.

Rule:

Don't use printf if you suspect it will ever contribute to a "Memory
Footprint" problem.

I hope you're not undertaking this project because someone violated
this rule.
Any of you have a suggestion on disabling all printf statements?

I also think about to add a common header file into the whole project.
However, I would need to put a #include "common.h" line into each c
file. It's gonna take a while to do that. Is there any way to insert
the line automatically into each c file?

The Microsoft Visual C++ compiler provides the /FI compiler option
(accurately labeled in the superlative help system as the "Name Forced
Include File" option):

"The /FIfilename option causes the preprocessor to process the header
file specified by filename. Each filename is included as if it were
specified with double quotation marks (") in an #include directive on
line 0 of every C or C++ source file specified in the CL environment
variable, on the command line, or in any command file. If multiple /FI
options are used, the files are included in the order they are
processed by CL. The space between /FI and filename is optional."

This is one of my favorite options. I use it to "compile" code, using
VC++, which is targeted for other compilers and platforms, such as
gcc/QNX/x86/PPC, Watcom/QNX, CVI/Windows, HI-TECH/PIC,
CodeComposer/TI-DSP, gcc/Atmel, etc. I can develop all of my code,
regardless of compiler/platform, in a single development environment,
thanks to Microsoft and the /FI option.

I don't know if gcc has a similar option. If not, you can always just
get the source code to gcc and modify it to implement the equivalent
of the /FI option. That's one of the beauty's of open source software,
isn't it?.

Best regards
 
B

Ben Pfaff

RedDevilDan said:
I also think about to add a common header file into the whole project.
However, I would need to put a #include "common.h" line into each c
file. It's gonna take a while to do that. Is there any way to insert
the line automatically into each c file?

Are you telling me you can't write a program to add one line of
text to each file in a collection of them?
 
J

jaysome

Are you telling me you can't write a program to add one line of
text to each file in a collection of them?

He may be telling you something like he wrote such a program but
because he forgot to check out the files from source control they were
read-only and his program failed to modify the files. And after hours
and hours of debugging his program, he finally got it working after
checking out the files from source control, only to suffer the wrath
of the Change Review Board (CRB) when they asked why so many source
files were modified. The source code modifications were straight
forward and trivial, but a CRB that only looks at statistics never
considered that. (Some CRBs are like a judge, and ironically, some
Federal Court Judges here in the US are like some CRBs).

If the OP had something like the Microsoft VC++ /FI option, as
described else-thread, he would have intuitively modified a Makefile
file or project file and added a header file and have been done with
it. That's adept, adroit, agile, astute, and, ultimately, awesome.
 
R

Richard Tobin

I am working on a Memory Footprint Reduction project. I came across an
idea to disable all printf statements so that less memory is required.

If you can add a header to each file, and you are using GCC, you can
put this in it (inside an ifdef that checks for GCC):

extern int printf(const char *format, ...) __attribute__ ((deprecated));

which will result in the message

warning: 'printf' is deprecated

when you compile a file that calls printf.

-- Richard
 
B

Ben Pfaff

jaysome said:
If the OP had something like the Microsoft VC++ /FI option, as
described else-thread, he would have intuitively modified a Makefile
file or project file and added a header file and have been done with
it. That's adept, adroit, agile, astute, and, ultimately, awesome.

....and can be rather a surprise when something goes wrong,
because there's nothing in the source code indicating that the
header file gets included.
 
F

Fred Kleinschmidt

RedDevilDan said:
I am working on a Memory Footprint Reduction project. I came across an
idea to disable all printf statements so that less memory is required.
In addition, when there is no single printf statement, the printf
library will not be linked, so it further reduces the executable size.
Is there an easy way to disable printf in a large project? In my
project, we have thousands of C & C++ files. They don't have a common
included common header. Otherwise, I can do a #define printf(x) in the
common header. I am using GNU GCC compiler and run the program in both
Linux and VxWorks platform.

Any of you have a suggestion on disabling all printf statements?

I also think about to add a common header file into the whole project.
However, I would need to put a #include "common.h" line into each c
file. It's gonna take a while to do that. Is there any way to insert
the line automatically into each c file?

Using a macro to disable printf will not work in the general case.
Suppose you had this:
#define printf(x)
or even using the variadic C99
#define printf(x,...)

But printf is a function that returns an int. Think what will happens if the
code contains:
if ( printf(....) != n ) {...}

One way around this is to add your own printf function that does nothing:

int printf( char *fmt, ... ) {}
 
R

Richard Heathfield

Fred Kleinschmidt said:
One way around this is to add your own printf function that does nothing:

int printf( char *fmt, ... ) {}

4.1.2 of C89 says: "All external identifiers declared in any of the headers
are reserved, whether or not the associated header is included."

7.1.3 of C99 says: "- Each identifier with file scope listed in any of the
following subclauses (including the future library directions) is reserved
for use as a macro name and as an identifier with file scope in the same
name space if any of its associated headers is included."

So - if you have a C99 compiler, that's fine **provided** that you don't
need anything else from <stdio.h>! But if you don't have a C99 compiler, it
ain't at all fine.
 
D

d3x0xr

#define printf( f,...) (1)

// or zero, printf can be used in an expression and needs to be an
expression result.
// that's it.

// provided you have a c99 compiler. GCC, OpenWatcom,...

RedDevilDan:
 
G

Guest

Richard said:
Fred Kleinschmidt said:



4.1.2 of C89 says: "All external identifiers declared in any of the headers
are reserved, whether or not the associated header is included."

7.1.3 of C99 says: "- Each identifier with file scope listed in any of the
following subclauses (including the future library directions) is reserved
for use as a macro name and as an identifier with file scope in the same
name space if any of its associated headers is included."

So - if you have a C99 compiler, that's fine **provided** that you don't
need anything else from <stdio.h>! But if you don't have a C99 compiler, it
ain't at all fine.

7.1.3 of C99 also says "All identiï¬ers with external linkage in any
of the following subclauses (including the future library directions)
are always reserved for use as identiï¬ers with external linkage."

It's not fine in C99, even if you don't use anything from <stdio.h>.
 
R

Richard Heathfield

Harald van Dijk said:

7.1.3 of C99 also says "All identifiers with external linkage in any
of the following subclauses (including the future library directions)
are always reserved for use as identifiers with external linkage."

It's not fine in C99, even if you don't use anything from <stdio.h>.

Good spot. Even without that, it's impractical (because just about every
program needs *something* from stdio.h), but with it, it's a wipe-out.
 
E

Ed Prochak

Richard said:
Harald van Dijk said:



Good spot. Even without that, it's impractical (because just about every
program needs *something* from stdio.h), but with it, it's a wipe-out.

I wonder why no one has suggested the real solution. Replace the
library.
But I guess that solution is really outside the realm of C.

Ed
 
A

Arthur J. O'Dwyer

Probably no. More likely the problem is that printf is a variadic
function (takes a varying number of arguments) so you need to
replace it a variadic macro.

Probably, the problem is that that line in stdio.h is

extern int printf(const char *fmt, ...);

which --- even with a variadic macro --- will become something like

extern int ((void)0);

which is just plain wrong. The most correct answers, already provided
by other posters, are "don't do that", "get a new library (without
printf)", and "get a new compiler (which can optimize out dead code)".

-Arthur,
intentionally conflating the concepts of "compiler" and "linker"
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top