
Inline adoc files when they are included exactly once. Also fix language tags because this inlining gives us better information on what language the code is written in.
87 lines
2.9 KiB
Plaintext
87 lines
2.9 KiB
Plaintext
== Why is this an issue?
|
|
|
|
When injecting ``++std::endl++`` into an output stream, two things happen:
|
|
|
|
* An end of line character ``++'\n'++`` is added to the stream
|
|
* The stream is flushed
|
|
|
|
In many situations, you don't need the stream to be flushed: It takes some time, and additionally, the stream is also flushed automatically in several circumstances:
|
|
|
|
* When the stream is closed
|
|
* In the case of ``++std::cout++``, each time an input is read on ``++std::cin++`` or an output is written on ``++std::cerr++``
|
|
* In the case of ``++std::cerr++``, each output is immediately written, the is no need to flush
|
|
|
|
Therefore, if your only goal is to add an end of line, ``++'\n'++`` is usually more efficient than ``++std::endl++``. If you do want to flush, you can be explicit and inject ``++std::flush++`` into the stream, or call the ``++flush++`` member function on the stream.
|
|
|
|
|
|
=== Noncompliant code example
|
|
|
|
[source,cpp]
|
|
----
|
|
void f() {
|
|
cout << "Hello world!" << endl << endl << "How are you?" << endl; // Noncompliant, 3 useless flushes
|
|
string s;
|
|
cin >> s;
|
|
cout << "Starting long operation now..." << endl; // Noncompliant, flushing is useful, but not explicit enough
|
|
longOperation();
|
|
cout << "Long operation is done" << endl; // Noncompliant
|
|
}
|
|
----
|
|
|
|
|
|
=== Compliant solution
|
|
|
|
[source,cpp]
|
|
----
|
|
void f() {
|
|
cout << R"(Hello world!
|
|
|
|
How are you?
|
|
)" << endl;
|
|
// Or
|
|
cout << "Hello world!\n\nHow are you?\n";
|
|
string s;
|
|
cin >> s;
|
|
cout << "Starting long operation now...\n" << flush;
|
|
longOperation();
|
|
cout << "Long operation is done\n";
|
|
}
|
|
----
|
|
|
|
|
|
== Resources
|
|
|
|
* https://github.com/isocpp/CppCoreGuidelines/blob/c553535fb8dda2839d13ab5f807ffbc66b63d67b/CppCoreGuidelines.md#sl50-avoid-endl[{cpp} Core Guidelines SL.50] - Avoid endl
|
|
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
'''
|
|
== Comments And Links
|
|
(visible only on this page)
|
|
|
|
=== on 19 Aug 2020, 00:32:48 Loïc Joly wrote:
|
|
We expect this rule to be quite verbose, for a limited value. But we believe it is still worth having it for its educational value.
|
|
|
|
We thought about having a rule trying to only detect uses of endl where we are confident that flushing is not needed (``++std::cout << "Hello" << endl << endl;++``) or several consecutive lines using endl without any function call in-between:
|
|
|
|
----
|
|
std::cout << "Hello" << endl;
|
|
std::cout << "Hello" << endl;
|
|
std::cout << "Hello" << endl;
|
|
----
|
|
But we believe it would be another rule (maybe part of SonarWay?), but still not much more valuable. So for now, we decided to stick to the simple rule.
|
|
|
|
|
|
Another option would be to flag only the cases where ``++\n++`` is more succinct than ``++endl++``:
|
|
|
|
|
|
----
|
|
std::cout << "Hello" << endl; // Noncompliant because...
|
|
std::cout << "Hello\n"; // ...alternative is shorter
|
|
std::cout << "Value:" << i << endl; // Compliant because...
|
|
std::cout << "Value:" << i << '\n'; // ...alternative is just as complex
|
|
----
|
|
But it is still favoring performances rather than correctness, which is usually not a great pattern...
|
|
|
|
endif::env-github,rspecator-view[]
|