Sign In Start Free Trial
Account

Add to playlist

Create a Playlist

Modal Close icon
You need to login to use this feature.
  • Book Overview & Buying Debunking C++ Myths
  • Table Of Contents Toc
  • Feedback & Rating feedback
Debunking C++ Myths

Debunking C++ Myths

By : Alexandru Bolboacă, Ferenc-Lajos Deák
close
close
Debunking C++ Myths

Debunking C++ Myths

By: Alexandru Bolboacă, Ferenc-Lajos Deák

Overview of this book

Think you know C++? Think again. For decades, C++ has been clouded by myths and misunderstandings—from its early design decisions to misconceptions that still linger today. Claims like "C++ is too hard to learn" or "C++ is obsolete" are often rooted in some truth, but they are outdated and fail to capture the language’s ongoing evolution and modern capabilities. Written by industry veterans with over 40 years of combined experience, this book uncovers the myths, exploring their origins and relevance in the context of today’s C++ landscape. It equips you with a deeper understanding of advanced features and best practices to elevate your projects. Each chapter tackles a specific misconception, shedding light on C++'s modern features, such as smart pointers, lambdas, and concurrency. You’ll learn practical strategies to navigate common challenges like code portability and compiler compatibility, as well as how to incorporate modern best practices into your C++ codebase to optimize performance and future-proof your projects. By the end of this book, you’ll have a comprehensive understanding of C++'s evolution, equipping you to make informed decisions and harness its powerful features to enhance your skills, coding practices, and projects.
Table of Contents (15 chapters)
close
close

The test-driven method for learning C++

Learning from books or structured courses is only one method; the other one is through personal exploration. Imagine learning C++, but instead of having to look through a bunch of code examples first, write the code as you think it should work and learn incrementally the differences between your intuition and the actual language. In fact, people naturally combine these two methods even when going through a structured learning course.

One downside of learning through exploration is that it’s hard to understand your progress, and you might often end up in difficult spots. A method comes to the rescue: TDD.

TDD is a counter-intuitive, effective method for incremental design. Its simplest description is the following:

  • Step 1, also known as red: Write one test that fails and shows the next case that needs to be implemented
  • Step 2, also known as green: Write the simplest code to make the test pass (and keep all the other tests passing)
  • Step 3, also known as refactor: Refactor the production code and the test code to simplify.

This red-green-refactor cycle repeats in very small cycles (often 5-10 minutes) until all the behaviors associated with the current feature or user story have been implemented.

Addressing TDD misconceptions

Personally, I am a fan of TDD, and I’ve used it for more than 10 years with a lot of success. In fact, I used TDD to write the sample code for this book. However, I know that TDD has been received with mixed feelings by the industry. Part of it is a failure in imagination, a common question being: How can I write a test for a method that doesn’t exist? Well, pretty much the same way in which you write code that hasn’t existed before: you imagine it’s there and focus on the desired inputs and outputs. Other criticism comes from failing to understand what TDD really is and how it works. Examples of faux TDD failures often involve starting with edge cases and showing that things get complicated very quickly when you should start with happy-path cases. Claims of TDD slowing down development are credible, but the truth is that this method helps us be more thorough and calculated, thus avoiding issues that are usually caught much later in the process and fixed with much sweat and stress. Finally, TDD is not a method for designing high-performing algorithms, but it can help you find a first solution that you later optimize with the help of a test suite.

To understand how to learn a programming language with a modified TDD cycle, we need to clarify two things about TDD. First, TDD is counter-intuitive because it requires a prolonged focus on the problem domain, while most programming courses teach us how to deal with the solution domain. Second, TDD is a method for incremental design; that is, finding a code structure that solves a specific problem in a step-by-step manner instead of all at once. These two characteristics make TDD the best fit for learning a new programming language, with some support.

Imagine that instead of learning the whole thing about C++ before being able to run a program, you just learn how to write a test. That is easy enough because tests tend to use a small subset of the language. Moreover, running the tests gives you instant feedback: failure or red when something is not right and success or green when everything is working fine. Finally, this allows you to explore a problem once you have one or more tests and figure out how to write the code such that the compiler understands it – which is what you want when you learn a language. It might be a bit problematic to figure out the error messages, particularly in C++, but if you have a person (or maybe an AI in the future) to ask for help, you’ll learn a lot on your way and see the green bar whenever you’ve learned something new.

This method has been tested on a small scale, and it worked remarkably well. Here’s how a learning session might work for C++.

Setup

At least two actors are involved in the learning process; we’ll call them the coach and the student. I prefer using a coach instead of the instructor because the goal is to guide the students on their own learning path rather than teach them things directly.

I will discuss the rest of the session as if only a student is involved. A similar setup can work with multiple students as well.

The first thing the actors need to do is to set a goal. Typically, the goal is to learn a minimum of C++, but it can also be learning more about a specific topic – for example, std::vector or STL algorithms.

In terms of the technical setup, this process works best with the two people watching the code on the same monitor and working side by side. While this is best done in person, remote is possible as well through various tools.

To start, the coach needs to set up a simple project composed of a test library, a production code file, and a test file. A simple way to run the tests needs to be provided, either as a button click, a keyboard shortcut, or a simple command. The setup I recommend for C++ is to use doctest (https://github.com/doctest/doctest), a header file-only test library that is very fast and supports a lot of the features needed for production.

Here’s the simplest structure for this project:

  • A test file, test.cpp
  • A production header file, prod.h
  • A doctest.h file
  • A Makefile allowing us to run the tests

A production cpp file may also be needed depending on the learning objectives.

The coach also needs to provide an example of a first test that fails and show how to run the tests. The student takes over the keyboard and runs the test as well. This test can be very simple, as in the following example:

#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "doctest.h" 
#include "prod.h"
TEST_CASE("Test Example"){
    auto anAnswer = answer();
    CHECK(anAnswer);
}

The production header shows the following:

bool answer(){
    return true;
}

The first order of business is then to make the test pass. The question the coach will keep asking the student is: “How do you think this will work? Write whatever you find intuitive.” If the student finds the correct answer, great! If not, show the correct answer and explain the reasons.

This example is very useful because it introduces a few elements of the language and shows them working: a function declaration, a variable, a test, and a return value. At the same time, the process is very nice because it gives the student a measure of progress: tests passing is good, and tests not passing means there’s something to learn.

With all these done, it’s time to enter the exploration phase.

Exploring the language

There are two ways to explore a programming language in this manner: through simple problems that introduce concepts one by one, also known as koans, or through solving a more complex problem.

Either way, the method stays the same: first, the coach writes a simple test or helps the student write a simple test that fails. Then, the student is asked to write the solution that seems most intuitive to them. Tests are run, and if they don’t pass, the coach needs to explain what is not working. Either the coach or the student makes the change, and when the tests pass, the step ends with clear progress.

During this process, it’s important to focus on the next natural step for the student. If the student has specific questions or curiosities, the next test can treat these instead of going through a scripted process. This adaptive way of learning helps students feel in charge, and the process gives them an illusion of autonomy that eventually turns into reality.

What about memory issues?

We spent some time in this chapter discussing the fact that C++ programmers need to learn more about memory management than their colleagues using other mainstream programming languages. How can they learn memory management with this method? Tests will not catch memory issues, will they?

Indeed, we want students to learn that they need to care about memory from the very beginning. Therefore, memory checks need to be integrated into our test suite. We have two options to do this: either use a specialized tool or select a test library that can detect memory issues.

A specialized tool such as valgrind is easy to integrate into our process. See the following example of a Makefile:

check-leaks: test 
    valgrind -q --leak-check=full ./out/tests
test: test.cpp
    ./out/tests
test.cpp: .FORCE
    mkdir -p out/
    g++ -std=c++20 -I"src/" "test.cpp"  -o out/tests
.FORCE:

The test.cpp target is compiling the tests. The test target depends on test.cpp and runs the tests. And the first target, check-leaks, runs valgrind automatically with options to show errors only when they come up so that students don’t get overwhelmed. When running make without any parameters, the first target is picked, so the memory analysis is done by default.

Assume we are running the tests with a memory leak, as in the following example:

bool answer(){
int* a = new int(4);
return true;
}

We are immediately greeted by this output:

==========================================================[doctest] test cases: 1 | 1 passed | 0 failed | 0 skipped
[doctest] assertions: 1 | 1 passed | 0 failed |
[doctest] Status: SUCCESS!
valgrind -q --leak-check=full ./out/tests
[doctest] doctest version is "2.4.11"
[doctest] run with "--help" for options
==========================================================[doctest] test cases: 1 | 1 passed | 0 failed | 0 skipped
[doctest] assertions: 1 | 1 passed | 0 failed |
[doctest] Status: SUCCESS!
==48400== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1
==48400==    at 0x4849013: operator new(unsigned long) ==48400==    by 0x124DC9: answer()

This output provides enough information for a conversation with the student.

The second option is to use a test library that already has memory leak detection implemented. CppUTest (http://cpputest.github.io/) is such a library, and it also has the advantage of supporting C and working for embedded code.

With these tools at our disposal, it’s now clear that this method works for teaching C++ to anyone who wants to try it or to dive deeper into specific parts, using exploration as a method.

Now that we learned two methods for learning C++ today, let’s go back to understanding what C++’s niche is and why it necessarily needs to be more complex than other languages.

bookmark search playlist download font-size

Change the font size

margin-width

Change margin width

day-mode

Change background colour

Close icon Search
Country selected

Close icon Your notes and bookmarks

Delete Bookmark

Modal Close icon
Are you sure you want to delete it?
Cancel
Yes, Delete

Confirmation

Modal Close icon
claim successful

Buy this book with your credits?

Modal Close icon
Are you sure you want to buy this book with one of your credits?
Close
YES, BUY