fclose(0)

I

Ian Collins

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.
But he or she would if a paying customer filed a bug report. That is,
unless he or she works for a well known supplier of non-compliant browsers.
 
I

Ian Collins

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.
See Richard's reply to your reply to my reply.
 
S

santosh

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.

Okay. I guess it says this somewhere else. IMHO, it should also have
been added to the description of fclose and other functions that are
not defined for a null pointer parameter.
 
S

santosh

Richard said:
Ian Collins said:
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.
But he or she would if a paying customer filed a bug report.

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.

I suppose Larry implied crashes during development and in-house testing.
But a crash isn't guaranteed even in this case. It's merely an outcome
on several common platforms.
 
S

santosh

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.

Yes. But is it an "error" to pass NULL to fclose? Elsewhere Richard
Tobin says that undefined behaviour is invoked when NULL is passed to a
library function whose definition does not *explicitly* accept NULL as
a valid parameter. The above description of fclose says nothing about a
call with NULL as argument, so presumably, undefined behaviour is
invoked at the point fclose(0) is called. One outcome would be to check
for NULL and return EOF (which DigitalMars seems to do), another would
be to blindly process the argument leading to God knows what.
 
B

Ben Bacarisse

CBFalconer said:
Sure you would. The EOF is not a normal return value. Something
failed.

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?
 
B

Bartc

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.

I don't think so. My projects require a low-level high-level mainstream
language like C. But there seem to be very few about other than C.

And I'm not going to change language because of some unexpected behaviour in
some library functions, that can be easily fixed with a few lines of code in
wrapper functions that already exist anyway.

I was just surprised at fclose() for example not already doing such a simple
check even if the standard doesn't require it to do so. But clearly it
would upset a lot of people if it were to suddenly behave sensibly.

Pointer values can be roughly grouped into these kinds:

(1) Pointing at the right thing
(2) Pointing at the wrong thing
(3) Containing an illegal address other than NULL
(4) Containing NULL

Of these, I would say (4) is the easiest to verify, and could easily be
placed in a library function. And I would also say it is a common error (to
have NULL where (1) is expected).

(3) is a little more difficult to check, and would probably be unreasonable
to expect most library functions to do so. (Although on some platforms, the
address range 0..N might be known to be invalid, and can be combined with a
check for NULL. This would trap many pointer errors like p+k where p has a
NULL value and k<=N.)

(2) might also be easily checkable in a few cases, for example in a FILE*
value where the beginning of a FILE struct is expected to contain some value
or other.
 
B

Bartc

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

I was thinking in terms of verifying pointer values passed to functions.

(4) of my list is easy. (3) and (2) are progressively more difficult. (1)
might be impossible (for the function to determine anyway).

3 on your list is again easy. But I wouldn't know how to test the others,
and if I did, the object in question might be the wrong one.
 
B

Ben Bacarisse

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.

<sigh> Forget it.
 

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

Similar Threads

Working with files 1
Command Line Arguments 0
code 34
[C language] Issue in the Lotka-Volterra model. 0
HELP:function at c returning (null) 4
please help a beginner 5
Problem with FCLOSE 11
comparison error 12

Members online

No members online now.

Forum statistics

Threads
473,778
Messages
2,569,605
Members
45,238
Latest member
Top CryptoPodcasts

Latest Threads

Top