11

In C++03 Standard observable behavior (1.9/6) includes calls to library I/O functions. Now I have this code:

printf( "" );

which is formally a call to a library I/O function but has no effect.

Is it observable behavior? Is the compiler allowed to eliminate it?

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • @Oli Charlesworth: Just as much as code optimization does. – sharptooth Aug 26 '11 at 14:40
  • @Bo Persson: Yes, if the compiler is not allowed to do that I get extra machine code. – sharptooth Aug 26 '11 at 14:42
  • 1
    @Oli - even if it doesn't matter that doesn't make it not an interesting question. – Flexo Aug 26 '11 at 14:51
  • Well, the 1.9/6 specifically says that yes, it's observable behavior and compiler can't eliminate it. I guess your real question is why, because we certainly wouldn't mind if it did that? – hamstergene Aug 26 '11 at 14:52
  • Are you sure it has no effect? Maybe it will trigger internally some timeout that flushes some buffers? Or buffers are flushed every N calls? – PlasmaHH Aug 26 '11 at 15:15

5 Answers5

5

It's certainly observable if sync_with_stdio is true. When that's true, printf("") forces synchronization with std::cout output, flushing previously buffered output.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • Are you sure `sync_with_stdio` may change how stdio performs, and not just how the C++ streams work, which might happen to cause strange things to the former? – Deduplicator Jul 03 '15 at 17:13
2

It would observable

  • if the output is redirected and the file was closed, truncated, or somehow has become invalid for output
  • if the stream state was 'bad' anyway

The point made about sync_with_... is also very relevant

sehe
  • 374,641
  • 47
  • 450
  • 633
1

I highly doubt it, since the behavior might become more highly visible in multithreaded programming if the OS chooses to context switch when the thread invoking printf blocks for I/O.

In that case, it will definitely have an effect if the results depend on how the threads is interleaved.

Platinum Azure
  • 45,269
  • 12
  • 110
  • 134
  • That's true, but the question was whether or not printing "had no effect" and was therefore not "observable". I was merely providing one case where it would have a real effect. Nowhere did I claim that this was from the standard. – Platinum Azure Aug 26 '11 at 15:05
  • 1
    @Platinum: I do not thing that context switching counts. All code modifications may affect context switching, yet optimizations are allowed. – Matthieu M. Aug 26 '11 at 15:35
1

In theory, you C library can be written in a way that flushes the buffer based on time. In that case, printing of empty string can result in a flush, thus producing a visible effect.

-3

Of course this has observable behavior - it must generate a call to write() system call with the underlying file descriptor. Making a system call is very observable behavior.

Consider as an extreme example that the file descriptor in the kernel may be serviced by a device driver that sounds siren every time it's write file operation is called (OK, somewhat of an artificial example, I'll admit :-) ...

gby
  • 14,900
  • 40
  • 57
  • couldn't the `write()` call quite legally *not* work on `0` terminated strings? – Flexo Aug 26 '11 at 14:48
  • 3
    I would have thought that the library (which buffers) would do a no-nop as zero bytes will be added to the buffer. The only observable evidence is nmore CPU usage. – Ed Heal Aug 26 '11 at 14:49
  • 1
    @Ed Heal - and if CPU usage is considered an observable behaviour then all optimisations are out! – Flexo Aug 26 '11 at 14:50
  • 1
    What if my computer sounds a siren every time ram is modified? Does incrementing an integer then qualify as observable behavior? – Benjamin Lindley Aug 26 '11 at 14:55
  • 3
    @Benjamin Lindley: LOL. I guess you wouldn't care - your life would be miserable anyway. – sharptooth Aug 26 '11 at 15:00
  • 1
    -1, wrong. There's no reason to assume a `write` call even exists. If the OS only has a `PUTCHAR(C)` call, the `printf` implementation will have to loop. And obviously looping over `""` will call `PUTCHAR` exactly zero times, i.e. non-observable. – MSalters Aug 26 '11 at 15:12
  • @MSSalters you are right of course that there needed be a right call. The point I was trying to make is that if printf is implemented on top an abstraction outside the program (e.g. system call) that receives whole strings (e.g. write()) then that call will be made for a NULL string - hence it is observable. – gby Aug 26 '11 at 15:29