I
Ian Collins
Says who? The behaviour is undefined.CBFalconer said:However fclose doesn't crash on receiving a NULL. It returns EOF.
Says who? The behaviour is undefined.CBFalconer said:However fclose doesn't crash on receiving a NULL. It returns EOF.
But he or she would if a paying customer filed a bug report. That is,Richard said:(e-mail address removed) said:
No, it's merely a useful consequence.
If that were true, it would be a pity that it isn't guaranteed by the
Standard. But it isn't true, of course. Some programmers never even see
the crashes, let alone fix their causes. For example, I have a web browser
written by someone else, which crashes whenever I accidentally click on a
PDF link and then click "cancel" on the subsequent dialog asking if I want
to hand over my firstborn to Adobe. Clearly the programmer never bothered
to test this execution path, so he has /not/ been forced to fix his
defective code.
See Richard's reply to your reply to my reply.CBFalconer said:Ian said:CBFalconer wrote:
.... snip ...
Says who? The behaviour is undefined.
Says the standard.
Returns
[#3] The fclose function returns zero if the stream was
successfully closed, or EOF if any errors were detected.
Note the phrase "any errors" in the line above.
Richard said:The standard *does* say that you get undefined behaviour if you pass
null to a library function expecting a pointer unless it explicitly
says you can. So the behaviour is certainly undefined.
Richard said:Ian Collins said:
But he or she would if a paying customer filed a bug report.Richard said:(e-mail address removed) said:
If this was the case then it would be better to admit it rather
than suggest, as a few people have, that crashing on passing a
null pointer is actually a good idea.
It *is* a good idea:
No, it's merely a useful consequence.
it forces programmers to fix their defective code.
If that were true, it would be a pity that it isn't guaranteed by
the Standard. But it isn't true, of course. Some programmers never
even see the crashes, let alone fix their causes. [example snipped]
Clearly the programmer never bothered to test this execution path,
so he has /not/ been forced to fix his defective code.
So what you're saying is that the crash in itself is not sufficient to
force the programmer to fix the defective code. This doesn't appear to
contradict anything I said above.
CBFalconer said:Ian said:CBFalconer wrote:
... snip ...
Says who? The behaviour is undefined.
Says the standard.
7.19.5.1 The fclose function
Synopsis
[#1]
#include <stdio.h>
int fclose(FILE *stream);
Description
[#2] The fclose function causes the stream pointed to by
stream to be flushed and the associated file to be closed.
Any unwritten buffered data for the stream are delivered to
the host environment to be written to the file; any unread
buffered data are discarded. The stream is disassociated
from the file. If the associated buffer was automatically
allocated, it is deallocated.
Returns
[#3] The fclose function returns zero if the stream was
successfully closed, or EOF if any errors were detected.
Note the phrase "any errors" in the line above.
CBFalconer said:Sure you would. The EOF is not a normal return value. Something
failed.
Eric Sosman said:Bartc wrote:
The good idea is not to pass a null pointer in the first place.
If you want a hand-holding language (and there's no shame in wanting
such a thing), you can find plenty of them.
pete said:I consider object pointer values into a different four groups:
1 address of an object
2 one past the address of an object
3 null pointer
4 indeterminate
CBFalconer said:Ben said:... snip ...
So, the poor user writes (and I *know* this is a fragment):
FILE *fp = fopen(argv[1], "r");
if (fp) {
/* ...processing... */
}
else fprintf(stderr, "Failed to open %s\n", argv[1]);
if (flose(fp) == EOF)
fprintf(stderr, "Error closing %s\n", argv[1]);
How can they tell, from the EOF return, that their code is not
portable? Note that that is what I claimed. Sure, they get the two
error messages, but they expect that, surely? How does the expected
error return help then to see the non-portability of the construct?
They write:
FILE *fp = fopen(argv[1], "r");
if (!fp) fprintf(stderr, "Failed to open %s\n", argv[1]);
else {
/* ...processing... */
if (flose(fp) == EOF)
fprintf(stderr, "Error closing %s\n", argv[1]);
}
Notice the inversion of if and else clauses. I think it is
clearer.
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.