fopen and fclose?

K

kathy

if fopen failed, does it necessary to call fclose?

I see an example like this:
....
stream = fopen(...);
if(stream == NULL)
{
....
}
else
{
....
}
fclose(stream);
....

By my understanding, it should like this:
....
stream = fopen(...);
if(stream == NULL)
{
....
}
else
{
....
fclose(stream);
}
 
V

Victor Bazarov

kathy said:
if fopen failed, does it necessary to call fclose?

No. And actually I can't find any description of what's going to happen
if you pass a null pointer to 'fclose'. Conclusion: it's undefined
behaviour and should be avoided. IOW, you must _not_ call 'fclose' for
a pointer obtained from 'fopen' if opening failed (and null pointer is
returned).

V
 
D

DraakUSA

It should be like this:

stream = fopen(...);
if (stream == NULL)
{
...
}
else
{
...
fclose(stream);
}

fclose'ing a NULL pointer is undefined and could cause problems.
fclose a stream ONLY iff it is a valid open stream.
 
M

mlimber

kathy said:
if fopen failed, does it necessary to call fclose?

It doesn't hurt anything to call fclose with a null pointer, and the
function will return an error code if it fails to close the supplied
file.
I see an example like this:
...
stream = fopen(...);
if(stream == NULL)
{
...
}
else
{
...
}
fclose(stream);
...

By my understanding, it should like this:
...
stream = fopen(...);
if(stream == NULL)
{
...
}
else
{
...
fclose(stream);
}

Your way is preferable, IMHO, but I think either is legal. Better still
might be to use std::fstream instead. :)

Cheers! --M
 
M

mlimber

mlimber said:
I stand corrected.

Hmm. On second... er, third thought, I'm not sure what the standard
mandates, but the IRIX 6.5 manpages do say: "For fclose, EOF is
returned if stream is NULL, or stream is not active, or there was an
error when flushing buffered writes, or there was an error closing the
underlying file descriptor."

Cheers! --M
 
D

Default User

mlimber wrote:

Hmm. On second... er, third thought, I'm not sure what the standard
mandates, but the IRIX 6.5 manpages do say: "For fclose, EOF is
returned if stream is NULL, or stream is not active, or there was an
error when flushing buffered writes, or there was an error closing the
underlying file descriptor."

IRIX man pages are not the Standard. There's no similar wording in
either the C or C++ standards.

Here's the wording from the C99 draft 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.



Brian
 
J

Jakob Bieling

Default User said:
7.19.5.1 The fclose function
Returns

[#3] The fclose function returns zero if the stream was
successfully closed, or EOF if any errors were detected.

Out of interest, could one not assume that "any error" will include
having passed 0 to fclose .. ?

regards
 
D

Default User

Jakob said:
Default User said:
7.19.5.1 The fclose function
Returns

[#3] The fclose function returns zero if the stream was
successfully closed, or EOF if any errors were detected.

Out of interest, could one not assume that "any error" will include
having passed 0 to fclose .. ?

Do you have some sort of support for that?

I think the fact that it differs from the implementation-specific man
page should tell you what you need to know.

Closing a null FILE* is UB.


Brian
 
R

Roland Pibinger

if fopen failed, does it necessary to call fclose?

I see an example like this:
...
stream = fopen(...);
if(stream == NULL)
{
...
}
else
{
...
}
fclose(stream);
...

By my understanding, it should like this:
...
stream = fopen(...);
if(stream == NULL)
{
...
}
else
{
...
fclose(stream);
}


else {
....
if (fclose(stream) == 0) {
// success
} else {
// error
}
}

Best wishes,
Roland Pibinger
 
J

Jakob Bieling

Default User said:
Jakob said:
Default User said:
7.19.5.1 The fclose function
Returns

[#3] The fclose function returns zero if the stream was
successfully closed, or EOF if any errors were detected.

Out of interest, could one not assume that "any error" will include
having passed 0 to fclose .. ?

Do you have some sort of support for that?

The only support is that paragraph you cited, since I do not call
fclose with a 0-pointer either (nor would I encourage anyone to do so).

Guess I am just complaining about them writing "any error", when in
fact passing a 0-pointer is not covered.
I think the fact that it differs from the implementation-specific man
page should tell you what you need to know.


Agreed.

regards
 
D

Default User

Jakob Bieling wrote:

Guess I am just complaining about them writing "any error", when in
fact passing a 0-pointer is not covered.


Many functions, especially those inherited from C, accept null pointers
without defined behavior. Notably most of the C-style string functions.



Brian
 
R

Ron Natalie

Default said:
Jakob Bieling wrote:




Many functions, especially those inherited from C, accept null pointers
without defined behavior. Notably most of the C-style string functions.
Absolutely, completely wrong.

7.1.4 of the C standard says that:

If an argument to a function has an invalid value (such as a value
outside the domain of the function, or a pointer outside the address
space of the program, OR A NULL POINTER, or a pointer to on-modifiable
storage when the corresponding parameter is not const-qualified) or a
type (after promotion) not expected by a function with variable number
of arguments, the behavior is undefined.

The string functions as does fclose, do not specify behavior for
being passed null behavior, hence by 7.1.4 the behavior is undefined.
 
B

Ben Pope

Ron said:
Absolutely, completely wrong.

7.1.4 of the C standard says that:

If an argument to a function has an invalid value (such as a value
outside the domain of the function, or a pointer outside the address
space of the program, OR A NULL POINTER, or a pointer to on-modifiable
storage when the corresponding parameter is not const-qualified) or a
type (after promotion) not expected by a function with variable number
of arguments, the behavior is undefined.

The string functions as does fclose, do not specify behavior for
being passed null behavior, hence by 7.1.4 the behavior is undefined.

I think you two are in violent agreement.

:p

Ben Pope
 
D

Default User

Ron said:
Absolutely, completely wrong.

I don't think so!
7.1.4 of the C standard says that:

If an argument to a function has an invalid value (such as a value
outside the domain of the function, or a pointer outside the address
space of the program, OR A NULL POINTER, or a pointer to on-modifiable
storage when the corresponding parameter is not const-qualified) or a
type (after promotion) not expected by a function with variable number
of arguments, the behavior is undefined.

Which is what I said, more or less.
The string functions as does fclose, do not specify behavior for
being passed null behavior, hence by 7.1.4 the behavior is undefined.

That's what I said, "without defined behavior".

I believe you misread what I wrote. Probably my phrasing wasn't the
best.



Brian
 
D

Default User

Ben said:
I think you two are in violent agreement.


I believe so. My phrasing "without defined behavior" probably threw Ron
off in his reading.

I might screw up in the details of C++, but I'm unlikely to make a
fundamental error in C :)



Brian
 
R

Ron Natalie

Default said:
I believe so. My phrasing "without defined behavior" probably threw Ron
off in his reading.

Yes there term "accept" allowed me to gloss over the difference between
"defined" and "undefined". We are in "violent agreement."
 
D

Default User

Ron said:
Default User wrote:

Yes there term "accept" allowed me to gloss over the difference
between "defined" and "undefined". We are in "violent agreement."

I was trying to avoid saying the Standard said it was UB, because in
most of these cases it just doesn't address what happens when you pass
in NULL. So I ended up with fairly clunky language that needed a
rewrite editor.



Brian
 

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

Forum statistics

Threads
473,731
Messages
2,569,432
Members
44,832
Latest member
GlennSmall

Latest Threads

Top