(void) printf vs printf

M

Malcolm

SM Ryan said:
What I'm wonderring is how do you report an error if printf doesn't
work? I usually use printf or fprintf or perror to print errors. If
the printf doesn't work how do you report the printf doesn't work?
exit(EXIT_FAILURE);
 
M

Malcolm

Christian Bau said:
printf returns a value.

When a function returns a value, and the programmer ignores the code, I
would want to know why. There are usually two explanations: The
programmer made a mistake ignoring the return value, or the programmer
did ignore the return value on purpose. When you write

printf (...);

I have no idea if you wanted to ignore the return value or not. If you
write

(void) printf (...);

it tells me that the programmer knew that printf returns a value, and
made a conscious decision to ignore that value. Do some professional
programming, try finding a few bugs in a million lines of other people's
code, and you will appreciate such things.
You have a point here.

printf() is actually a bad example, since everyone knows what the fucntion
does, and that it is unusual to be interested in the return value.
However if functionx return a value, then normally you would expect that
value to be useful. It is quite common for functions to return error codes,
and for sloppy programmers to neglect to check the error. So an explicit
cast would be useful.

The problem is that if you impose this a standard then the sloppy
programmers might just get into the habit of writing (void) anyway.

(void) functionx(x, y);

is also hard on the eye.
By itself the cast doesn't detract too much from readbility, but just look
at this

(void) glib_MoveMouseCursor( (float) cursor.x_loc, (float) cursor.y_loc);

Now we've got something pretty unreadable, highly error-prone, and what is
making it that way is the casts and structure member names that are intended
as aids to the programmer.
 
C

CBFalconer

Malcolm said:
exit(EXIT_FAILURE);

I had a medical message system some years ago. It delivered test
results to nursing stations. All messages were inserted with an
'alternate destination', such as the floor supervisor. If delivery
(and retries over a configured time limit) failed the message was
wrapped with a header identifying it as rerouted and sent to the
alternate location. The same rules applied here, implemented by
making the reroute wrapper set the alternate to the system
console. If that also failed the machinery was busted, and
probably wasn't accepting the messages from the mainframe in the
first place.

Just as an illustration of handling output failure.

--
Some informative links:
http://www.geocities.com/nnqweb/
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.caliburn.nl/topposting.html
http://www.netmeister.org/news/learn2quote.html
 
M

Malcolm

No Such Luck said:
Interesting. I knew things like successful file openings should be
error checked, and pointers should be checked before accessing, etc.
But printfs? What is usually the accepted degree of error checking?
It depends on your application. A video game is either playable or it isn't,
and usually you have no facilities for issuing patches, so no error messages
are produced. An error message just irritates the customer when he calls
only to be told "yes it was our fault but we can't do anything about it".

If you are writing embedded software for a life-support system, on the other
hand, you probably want a detailed log of every little thing that goes
wrong, and you would have a list of customers whom you would contact in the
event of a problem being reported. The customer would usually have a trined
technician who could roll back to a stabler previous version, or shut off
certain functions, if the problem was serious enough.
 
M

mcp_achindra

(void) printf(...) Vs printf(...)

Well I think I figured out, what it all means. We have been running
all the way on the wrong tracks.

The ANSI/ISO C Standards Documentation - States

"Portable Codes - Strictly Conforming"

- only uses specified features
- doesn't exceed any implementation-defined limits
- has no output that depends on implementation -defined, unspecified
or undefined limits.

This intends to describe maximum portable programs, which will always
produce same output, what ever they are run on.

To make a program portable, one must put the necessary casts, return
values adn so on.

Thus it is now clear thet (void) printf(...) Vs printf(...) is merely
an implementation issue and this makes the code portable over various
platforms.
 
E

Eric Sosman

mcp_achindra said:
(void) printf(...) Vs printf(...)

Well I think I figured out, what it all means. We have been running
all the way on the wrong tracks.

The ANSI/ISO C Standards Documentation - States

"Portable Codes - Strictly Conforming"

- only uses specified features
- doesn't exceed any implementation-defined limits
- has no output that depends on implementation -defined, unspecified
or undefined limits.

This intends to describe maximum portable programs, which will always
produce same output, what ever they are run on.

To make a program portable, one must put the necessary casts, return
values adn so on.

Thus it is now clear thet (void) printf(...) Vs printf(...) is merely
an implementation issue and this makes the code portable over various
platforms.

It's not about portability, but about documentation.

C has various kinds of statements: return, if, { blocks },
and others. One frequently-used type of executable statement
consists only of an expression followed by a semicolon, as in

x = 3; /* the `=' operator and two operands */
i++; /* the suffix `++' operator and one operand */
f(); /* the `()' operator and one operand */

The interesting thing about an expression is that it yields
a value. Yes, even the `=' operator produces a value, in addition
to the effect of storing something: in `x = 3;' the value of the
entire expression is three, converted to the type of `x'.

Sometimes you don't care about the value of an expression;
you evaluate it only for its side-effects. You probably write
`x = 3;' just to store a new value in `x', making no use of the
expression's value. You probably write `i++;' just to increment
`i', and you don't use the previous value (which is the value
of the expression) at all. You probably write `f();' just to
accomplish whatever side-effects the function produces, not
caring about the value it returns.

... and that's where the `(void)' casts come in. The printf()
function returns a value: either the number of characters that
were printed, or a negative value to indicate an output error.
You frequently don't care how many characters were printed, and
you may not feel like checking for errors (either through general
sloppiness or because you plan to check with ferror(stdout) later
on). Yet, the function actually does return a value -- and some
source-checking tools like lint will issue all kinds of warnings
about ignoring that value. This can have the unpleasant effect of
producing so many warnings about printf() calls that the important
messages just get lost in the flood.

So you write `(void)printf(...);' as a way of "using" the
returned value: you "use" it by throwing it away, which has the
effect of ignoring it but is more explicit. "Quiet, lint," you
are saying, "I know that I'm ignoring the value, and it's not
an oversight you should complain about." The program does the
same thing with or without the `(void)' cast, so there's no
issue about portability; the cast amounts to documentation that
tells lint -- or a human reader -- that you really intended to
ignore the returned value.

Personally, I think such casts are just unpleasant clutter:
the way to silence lint-like tools is to make the tools smarter,
not to cater to their nervousness. But some coding standards
require such things (and the position is not unreasonable; maybe
one *should* pay attention to the possibility that the output
never went anywhere), so I can't really make a cast that the
`(void)' cast is a Bad Thing. You pays your money, and you takes
your choice.
 
K

Keith Thompson

(void) printf(...) Vs printf(...)

Well I think I figured out, what it all means. We have been running
all the way on the wrong tracks.

The ANSI/ISO C Standards Documentation - States

"Portable Codes - Strictly Conforming"

- only uses specified features
- doesn't exceed any implementation-defined limits
- has no output that depends on implementation -defined, unspecified
or undefined limits.

This intends to describe maximum portable programs, which will always
produce same output, what ever they are run on.

Yes, but this has nothing to do with casting the result of printf.
To make a program portable, one must put the necessary casts, return
values adn so on.
No.

Thus it is now clear thet (void) printf(...) Vs printf(...) is merely
an implementation issue and this makes the code portable over various
platforms.

No, it doesn't make the code more portable. The statements
printf("hello, world\n");
and
(void)printf("hello, world\n");
are exactly equivalent; they both invoke the printf() function with the
specified argument and ignore the result.

Casting the result makes it more explicit to the reader that you're
ignoring the result returned by the printf function, but there's no
difference as far as the compiler is concerned.

The cast might inhibit a warning from some over-eager compiler or from
a lint-like tool, but that's not a portability issue. No compiler
will accept one and reject the other.
 
A

achindrabhatnagar

Portable Code should be strictly-conforming

strictly-conforming- A strictly-conforming program is one that:

· only uses specified features.
· doesn't exceed any implementation-defined limit.
· ***has no output that depends on implementation-defined,
unspecified, or undefined features.***

This was intended to describe maximally portable programs, which will
always produce the identical output whatever they are run on. For
example, the following program is not strictly conforming:

#include <limits.h>
#include <stdio.h>
int main() { (void) printf("biggest int is %d", INT_MAX);
return 0;}
/* not strictly conforming: implementation-defined output! */

Program portability is valuable, so we should always put the necessary
casts, return values, and so on in your real-world code.

conforming- A conforming program can depend on the nonportable
features of an implementation. So a program is conforming with respect
to a specific implementation, and the same program may be nonconforming
using a different compiler. It can have extensions, but not extensions
that alter the behavior of a strictly-conforming program. This rule is
not a constraint, however, so don't expect the compiler to warn you
about violations that render your program nonconforming!

The program example above is conforming.


I believe... (void) printf(...) is a matter of Understandability!

The KEY POINT of this whole text is to show that the fundamental
difference between correctness and understandability. If we lose
understandability in an attempt to gain correctness, we will lose in
the end.

Always place understandability as a priority ABOVE correctness. In the
end, if a program is more understandable, the chances it can be fixed
correctly will be much higher.
 
K

Keith Thompson

Portable Code should be strictly-conforming

strictly-conforming- A strictly-conforming program is one that:

· only uses specified features.
· doesn't exceed any implementation-defined limit.
· ***has no output that depends on implementation-defined,
unspecified, or undefined features.***

This was intended to describe maximally portable programs, which will
always produce the identical output whatever they are run on. For
example, the following program is not strictly conforming:

#include <limits.h>
#include <stdio.h>
int main() { (void) printf("biggest int is %d", INT_MAX);
return 0;}
/* not strictly conforming: implementation-defined output! */

It's also implementation-defined whether the program produces any
output at all. Add a \n to the end of the string literal.
Program portability is valuable, so we should always put the necessary
casts, return values, and so on in your real-world code.

Casts are rarely necessary; the cast in the above program is certainly
not necessary. It does make it explicit that the value returned by
printf() is ignored.
conforming- A conforming program can depend on the nonportable
features of an implementation. So a program is conforming with respect
to a specific implementation, and the same program may be nonconforming
using a different compiler.
Ok.

It can have extensions, but not extensions
that alter the behavior of a strictly-conforming program.

I think you mean that a conforming *implementation*, not a conforming
program, can have extensions.
This rule is
not a constraint, however, so don't expect the compiler to warn you
about violations that render your program nonconforming!

If a conforming implementation accepts your program, then it is a
conforming program by definition. The class of "conforming programs"
actually turns out not to be a very useful concept.
The program example above is conforming.


I believe... (void) printf(...) is a matter of Understandability!

The KEY POINT of this whole text is to show that the fundamental
difference between correctness and understandability. If we lose
understandability in an attempt to gain correctness, we will lose in
the end.

Always place understandability as a priority ABOVE correctness. In the
end, if a program is more understandable, the chances it can be fixed
correctly will be much higher.

I *think* the point of your article was that
(void)printf("whatever\n");
is better than
printf("whatever\n");

There is no difference between them in terms of conformance or
portability, so I'm not sure why you spent so much time discussing
them.

As for understandability, I personally find the statement clearer
without the cast. Any C programmer should know perfectly well that if
a printf appears in a statement context, the result is discarded.
It's common practice *not* to explicitly cast the result of printf().
 
P

pete

Portable Code should be strictly-conforming

I disagree.
Portable Code should be Correct Code.

ISO/IEC 2382-l : 1993 (E/F)

01.04.06 01.04.06
portability (of a program)
The capability of a program to be executed on various types
of data processing systems without converting the program
to a different language and with little or no modification.
 

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,774
Messages
2,569,599
Members
45,163
Latest member
Sasha15427
Top