#freopen() clarification
77 messages · Page 1 of 1 (latest)
When your question is answered use !solved to mark the question as resolved.
Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.
The standard says "The freopen function first attempts to close any file that is associated with the specified stream.Failure to close the file is ignored." So I think it always closes the old file
That's only in the case filename is specified in, the case it's not it say this:```
If filename is a null pointer, the function attempts to change the mode of the stream. Although a particular library implementation is allowed to restrict the changes permitted, and under which circumstances.
At least going by this doc: https://cplusplus.com/reference/cstdio/freopen/
Doesn't say anything about closing the file in that case
It doesn't say otherwise for this
The case for NULL filename even says "as if the name of the file currently associated with the stream had been used"
which doc you reading?
7.23.5.4 The freopen function
I guess it does say that "Failure to close the file is ignored" so it may still be open at the end but idk how you'd check for that
I don't think the standard provides a way to check if the file is still open
hmm, guess I'll need to just skip the FILE* interface and just use the raw interfaces instead with wrappers. That's annoying but workable, better than UB
Where would the UB come from?
The UB is wether the stream parameter is still open in the case of failing to change mode
and since the standard doesn't clearly define that it's UB
Leaving a file open isn't UB
but that's the thing, if freopen fails and returns NULL it's not clear if I should then attempt to close what I gave the stream parameter
I either risk a dangling file pointer when existing after a failed reopen or risk a segfault by trying to close it. Neither is a good solution honestly
Well anyways no that it's been made clear to me the particular scenario I needed clarifying is UB
!solved
Thank you and let us know if you have any more questions!
This thread is now set to auto-hide after an hour of inactivity
if freopen fails you can still use the file
But it says it first closes the file
which would make the stream invalid
how could you say recover from freopen failing when using it with stdout
if you couldn't close stdout afterwards
I wouldn't do that in the 1st place
it's definitely one of the intended use cases
I would be dabbling with the raw handles in that case since I don't want UB
hm seems like that is the case
strange
I wish there was something like fchangemode() which at least would be clear about not closing the file ever
tmpfile can return null anyway, so I don't see what that would change
Ah, yeah that one's just a bug on my part, forgetting to put the line after the if statement
the wording about it seems pretty clear to me now
it says it first attempts to close the stream
that specified by mode``` indicates to me it tries to keep the file open instead in that particular scenario
if it had been said "freopen in both cases first closes..." then yeah, it would be clear what happens but it doesn't so it's not
well glibc closes the file even in this case
also, the standard often gives special cases to null without saying "both cases" like you're expecting
and what about crt? or whatever the mac version does?
As far as I'm concerned if it doesn't clearly state what would happen in the scenario then it's UB by default
windows documentation just says "Each of these functions returns a pointer to the newly opened file. If an error occurs, the original file is closed, and the function returns a NULL pointer value."
doesn't even mention that filename can be null
So now there's implementation UB too? Yeah I'm not going to use the standard FILE* for this particular scenario, too unreliable
basically you shouldn't interpret filename being null as a special case where all of the other wording has no effect, just think of it as being a default where it fills in the current file name
so the rule about closing the file still applies
on windows to even be able to open all possible files, you have to use one of their non-standard extensions
like _wfopen
Not really, I think there was some prefix that could add to paths to allow extended UTF-8 paths
not all file names have to be valid UTF-16
:)
Yeah, one problem at a time please
if you create an unpaired surrogated code unit then you can't open it with a UTF-8 path
I can circle back to the non-unicode paths issue later after I've gotten my project to do it's expected tasks in unicode
but I don't really see how your interpretation could make sense
If filename is a null pointer, the freopen function attempts to change the mode of the stream to
that specified by mode, as if the name of the file currently associated with the stream had been
used. It is implementation-defined which changes of mode are permitted (if any), and under what
circumstances.The freopen function first attempts to close any file that is associated with the specified stream.
Failure to close the file is ignored. The error and end-of-file indicators for the stream are cleared.
Section 7.23.5.4 "The freopen function" Paragraphs 3 and 4 C23
Neither do I see it making implementation sense, the fact remains however the standards left it open to interpretation by not defining clearly what should happen
clearly, it closes the file first before attempting to change the mode
given that it says first
No it doesn't, it doesn't make clear that it doesn't just apply to the renaming situation but to the mode change situation also
It's left up in the air as what was actually meant so it's implementation defined at that point which makes it UB in my book
do you also think the error and end of file indicators aren't cleared when changing the mode?
that should be much easier to verify
It's possible, though in this particular case it doesn't matter as nothing was written by this point anyways
I just don't think you're reading it correctly
I expect this file to live in ram only for it's lifetime so it's completely ok for it to still be at position 0 with length 0 when I start using it
I only need to be sure I've not caused a memory leak by relying on UB to be what I want it to be (which going by what you've said it is for now at least what I want it to be)
Ultimately the standard has not given me confidence I can still rely on the handle I was given at the start nor can I rely on the handle to be closed if freopen happens to fail (albeit unlikely in this particular scenario)
also was there anything wrong with just using binary mode
(if it's fine, then you can get around thinking about this)