Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 569
ApproachingDarknessFish Avatar asked Mar 31 '13 00:03

ApproachingDarknessFish


People also ask

Is it possible to modify a string literal?

The behavior is undefined if a program attempts to modify any portion of a string literal. Modifying a string literal frequently results in an access violation because string literals are typically stored in read-only memory.

What are the two types of string literals?

A string literal with the prefix L is a wide string literal. A string literal without the prefix L is an ordinary or narrow string literal. The type of narrow string literal is array of char .

How many types of string literals are there?

There are three sets of literal types available in TypeScript today: strings, numbers, and booleans; by using literal types you can allow an exact value which a string, number, or boolean must have.

What is char in string literal?

1) character string literal: The type of the literal is char[N], where N is the size of the string in code units of the execution narrow encoding, including the null terminator. Each char element in the array is initialized from the next character in s-char-sequence using the execution character set.


2 Answers

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.
like image 89
Mats Petersson Avatar answered Oct 13 '22 22:10

Mats Petersson


The different between string literal \n and endl is that:

\n is a string literal that get appended to stdout. endl will also append the newline character to stdout, however, it will also flush the stdout buffer. Therefore, it may take more processing. Other than this, there should be no practical difference.

like image 29
taocp Avatar answered Oct 13 '22 23:10

taocp