I was going over some old C code (listed below) with a view to re-using it in a new project, and I realised I had left off the final return statement. The peculiar thing is that the routine worked perfectly and did return the correct file pointer. Can anyone explain to me why this is?
FILE* openforwrite(char *name, int binary)
{
//broken out from main to keep it tidy and allow multiple output files.
FILE *file;
//first see if it exists
file = fopen(name,"r");
if (file)
{ // it does, delete it
fclose(file);
if(remove(name)) bail("Output file already exists and cannot be deleted.");
}
//now lets re-create and open it for writing
if (binary)
file = fopen(name, "wb");
else
file = fopen(name, "w");
//check it actually opened
if (!file)
bail("Error opening output file.");
//and pass the pointer back
return file; // <-- I had omitted this line initially but the routine still worked
}
The return value of the fopen call would end up putting the file handle in the register that is commonly used for return values (e.g., eax). If nothing changed that register value before the function exited, it could still be available for the caller. If, for example, you had one more function call after the fopen and before the end of the function, then it would likely have overwritten the eax register and failed for sure. As others have said, it is undefined behavior. Nonetheless, it is initially a very puzzling situation (and rather interesting).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With