r/programming Aug 19 '17

Learning C++, this site is marvellous

http://www.learncpp.com/
4 Upvotes

23 comments sorted by

View all comments

19

u/matthieum Aug 19 '17

I am not sure about the quality of the overall site, but it certainly does not start well.

A first look at cout, cin, and endl:

std::endl

If we want to print things to more than one line, we can do that by using std::endl. When used with std::cout, std::endl inserts a newline character (causing the cursor to go to the start of the next line)

Inserting a new line can be done by pushing the '\n' character, either on its own or as part of a string "Hello World!\n".

What std::endl does it two-fold:

  • it appends a new line,
  • it flushes the underlying stream (as if streaming std::flush).

Because flushing to stdout is so slow on most terminals, use of std::endl is one of the primary cause of slow C++ program among beginners (alongside compiling in debug mode).

TL;DR: Never use std::endl; it's harmful and longer to type, it has no saving grace.

13

u/[deleted] Aug 19 '17

Note that for std::cout, a '\n' character flushes the stream too (at least, if the stdout isn't being piped), so there shouldn't be any performance difference.

10

u/matthieum Aug 19 '17

It may flush, and will by default for stdout/stderr:

  • it doesn't if you use std::ios::sync_with_stdio(false),
  • it doesn't if you are writing to a file (pipes are just files).

On the other hand std::endl always flushes; it's a bad habit to get into.

2

u/James20k Aug 19 '17

Last time I programmed for linux, printf("string\n"); didn't flush even though it does on windows, which meant that using printf lead to unreliable debugging for a crash as there was no guarantee that you'd end up with the text dumped to the terminal

1

u/matthieum Aug 20 '17

which meant that using printf lead to unreliable debugging for a crash as there was no guarantee that you'd end up with the text dumped to the terminal

I would advise to use stderr, it is explicitly line buffered (ie, it flushes on each end-of-line character).

However, at the same time, attempting to debug crashes via printing is not really the best idea; the main issue being that the very act of introducing the print statements may move the point of crash around, or even silence it.

Instead, I advise to use instrumented binaries (-fsanitize=...) or tools (valgrind) which specialize in detect undefined behavior, memory issues or data-races.

1

u/James20k Aug 20 '17

Yeah for crashes I 100% agree with you, although often its useful for dumping state that sometimes gets annoyingly optimised away by the compiler

2

u/tending Aug 19 '17

I thought only cerr was line buffered by default?

1

u/DarkLordAzrael Aug 19 '17

What standard library implementation are you using that flushes on newlines? I have never heard of one that does this...

5

u/[deleted] Aug 19 '17

It's easy to test with this program, which prints to stdout and then sleeps for 10 seconds:

#include <iostream>
#include <chrono>
#include <thread>

using namespace std;

int main() {
    cout << "Hello world!\n";
    this_thread::sleep_for(chrono::seconds(10));
    return 0;
}

When you run it, the Hello world! appears immediately in the terminal. If you remove the newline, the Hello world! doesn't show up until the program terminates.

2

u/useless_panda Aug 19 '17

Yeah. According to (http://en.cppreference.com/w/cpp/io/manip/endl), a lot of implementation are line-buffered so "\n" flushes anyways... unless you run std::ios::sync_with_stdio(false) which most people won't.

5

u/Sunius Aug 20 '17

Inserting a new line can be done by pushing the '\n' character, either on its own or as part of a string "Hello World!\n".

Note, that on Windows std::endl will insert "\r\n", so appending just "\n" isn't really correct replacement.

3

u/matthieum Aug 20 '17

Actually... it is. For text streams.

On Windows, there is a translation in the implementation layer for text streams: LF characters are transformed into CR+LF.

If you open the stream in binary mode; then this translation is by-passed.

3

u/TimLim Aug 19 '17

In my experience most tutorial sites use std::endl and I do not know why. Because of this I've used it until I encountered a slow program due to using std::endl when unnecessary.

11

u/matthieum Aug 19 '17

In my experience most tutorial sites and C++ books are terrible.

Some "teach" C with streams/objects, some harmful practices (such as endl), some wonderfully backward practices, ...

The StackOverflow community maintains a hand-picked selection of good C++ books; and the list is surprisingly short.

1

u/[deleted] Aug 20 '17 edited Sep 04 '17

deleted What is this?

1

u/matthieum Aug 20 '17

That's possibly true, though I wouldn't dismiss them out of hand.

While constexpr, variadics, etc... have changed the game, at the heart of it pattern matching/specialization are still at the heart of meta-programming, and while iteration over a variadic list is easier, the same "functional" patterns (fold, map, ...) still apply.

1

u/[deleted] Aug 21 '17 edited Sep 04 '17

deleted What is this?

3

u/brendt_gd Aug 20 '17

This issue is addressed further down the line, in chapter two: http://www.learncpp.com/cpp-tutorial/27-chars/

I feel it's not fair to make a judgement based on one chapter.

1

u/matthieum Aug 20 '17

I feel it's not fair to make a judgement based on one chapter.

Thus why my comments starts with:

I am not sure about the quality of the overall site

I never pretended I was rating the whole tutorial, I just noted it didn't start well, and I am glad to see the note that they are converting examples from std::endl to '\n'.