Search code examples
c++charnewlinestring-literals

Are 1-character string literals ever optimized to simple char type literals?


Often when coding in C++, I will end cout statements with a newline (\n). However, my instinct has always been to express this newline as a string literal: "\n", even though it is a single character and can be expressed more efficiently as a char literal ('\n'). For instance:

cout << "The value of var is " << var << "\n";

There is a lot of code with this phenomenon. So, the question is as follows:

  1. Is there any difference whatsoever in the efficiency of the two different ways of expressing the newline character constant? I am not concerned about making any actual difference in the execution of the produced program (which I guess would be trivial); rather it just bugs me that some efficiency, however minuscule, might be lost for no reason.

  2. If the string-literal version is less efficient, will the compiler optimize it to the character constant version, as the two provide the exact same behavior?

  3. I am also familiar with std::endl. The documentation says that "This manipulator is often mistakenly used when a simple newline is desired, leading to poor buffering performance." And points to this article for more information. However, that article states the the "poor performance" mentioned only applies to file I/O and that using endl for writing to the screen may actually improve performance. What's the deal with this?

I've searched the C++ standard library but couldn't find the implementations of the relevant overloads of the << operator. I found the declarations in ostream.tcc:

extern template ostream& operator<<(ostream&, char);
extern template ostream& operator<<(ostream&, const char*);

But no clues as to how the mechanics boil down in the implementation.

This is more of a theoretical question than anything, so I'm not interested in reading "There is no pratical difference between the two." I know that. I'm just wondering whether there is any difference at all and how the compiler deals with that.


Solution

  • They are probably optimized to one string (per compilation unit) - most compilers will "merge strings of the same content".

    I'd expect there to be very little practical difference, other than the fact that you pass a pointer to a single char string.

    To your concrete questions:

    1. Yes, there is a slight difference, as a char * will require some indirection and thus generate a few extra instructions to be executed. For console output (rather than output to file) it's not important, as scrolling the console, even in full-screen text mode is > 100x more instructions.
    2. Doubt it.
    3. So std::endl will flush the buffer, which does indeed reduce output to files, because partial sectors or blocks are being written to the file, which increases the system call overhead. If you use "\n", the file is not being flushed until the buffer itself is filled, which would be at the very least 512 bytes, possibly as much as several tens of kilobytes. But as for answer #1, the console output performance will be more dependent on the speed that the screen can scroll.