0

I found this interesting behaviour in the following c++ program.

#include <fstream>

void append(std::string path, int i){
   FILE *out = fopen(&path[0], "a");
   fprintf(out, "%d\n", i);
   //fclose(out);
}

int main(){
   for(int i=0; i<3; i++) append("./text.txt",i);
   return 0;
}

where I forget to close the file in append.

Then the content of text.txt after one execution will be

2
1
0

other than

0
1
2

Once I fclose the file correctly, this effect will disappear.

I wonder how does this happen? BTW, I'm running it on a Ubuntu machine.

  • ***I wonder how does this happen?*** I believe its undefined behavior to have the same file open multiple times writing to the file. – drescherjm Jul 05 '22 at 14:56
  • @drescherjm, the behaviour is that append text becomes prepend text. – sicheng mao Jul 05 '22 at 14:57
  • 4
    I don't see an `fstream` used anywhere in this code. – Nathan Pierson Jul 05 '22 at 14:58
  • 2
    The files are closed/flushed in opposite order of opening them probably, but still, UB. `&path[0]` is a bad idea btw, it can cause UB as well, use `path.c_str()` or use the filesystem library for C++ rather. – Ulrich Eckhardt Jul 05 '22 at 14:58
  • You are witnessing the effects of buffering. Every open file will be closed and its buffers will be flushed when the program exits, but in what order is anyone's guess. – n. m. could be an AI Jul 05 '22 at 14:59
  • @NathanPierson Sorry, I thought this tag means I include the ... – sicheng mao Jul 05 '22 at 14:59
  • 3
    His point is you included fstream but instead did not use an fstream. You used `FILE *out = fopen(&path[0], "a");` which is from the `c` language and not an fstream. – drescherjm Jul 05 '22 at 15:00
  • 1
    @UlrichEckhardt I'm new to C++ so I'm not familiar with the standard operation. Thank you for your advice. – sicheng mao Jul 05 '22 at 15:03
  • You may want to learn the basics of [undefined behavior](https://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior), a concept that's usually pretty surprising for people who haven't worked with C and C++ much. Essentially, there's some code you can write where the compiler can do absolutely whatever it wants when resolving it. When this happens, reasoning about _exactly_ why the compiler chose to do what it did is usually difficult and not very informative. Your code appears to be one such case. – Nathan Pierson Jul 05 '22 at 15:06
  • @drescherjm oh, but it seems that my vscode raises an error that FILE is undefined if I don't include it. – sicheng mao Jul 05 '22 at 15:06
  • 1
    @sichengmao `FILE` is defined in ``. Your specific environment must coincidentally include when you include . That can not be relied upon, though. – Drew Dormann Jul 05 '22 at 15:08
  • 1
    https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list -- bookmark that, @sichengmao! :) – Ulrich Eckhardt Jul 05 '22 at 15:08
  • Thanks for all of your kind suggestions! – sicheng mao Jul 05 '22 at 15:12
  • Code is a description of program behaviour. The compiler takes the code, interprets the behaviour, and generates the machine instructions necessary to accomplish the described behaviour. If the described behaviour is open to multiple interpretations, watch out. – user4581301 Jul 05 '22 at 15:29
  • It it worth mentioning that `fopen` yields a *buffered file stream* object, not just file. So `fprintf` and similar functions are usually writing to the buffer and resent data does not get to the actual file until stream is flushed. Additionally, if you want to make sure that written data is really written to the disc then you may need to rely on some OS-specific API. – user7860670 Jul 05 '22 at 15:39

0 Answers0