Blog 6 min read

Modernize C++ Codebase: Banned C++ Features Guide

Share this article
Modernize C++ Codebase: Banned C++ Features Guide

Refactoring bezeichnet den Prozess, ein Softwaresystem so zu verändern, dass sich das von außen beobachtbare Verhalten des Codes nicht ändert, seine interne Struktur jedoch verbessert wird.

Bei der Organisation von Code-Refactoring lassen sich typischerweise drei Vorgehensweisen unterscheiden:

  • Iteratives Refactoring: Eine Anwendung lässt sich nicht bereits in der ersten Iteration perfekt entwickeln – selbst mit den besten Architekten, Designern und Entwicklern. Ein pragmatischer Ansatz besteht darin, Refactoring in den Entwicklungsprozess zu integrieren und nach jeder Iteration durchzuführen, ohne dafür unverhältnismäßig viel Geld oder Zeit aufzuwenden. Iterative refactoring
  • Refactoring bei Bedarf: Nach der Bereitstellung einer Anwendung werden häufig Fehler gemeldet. Wenn deren Behebung sehr zeitaufwendig ist oder sich neue Kundenanforderungen nur schwer in das bestehende System integrieren lassen, kann Refactoring eine gute Möglichkeit sein, die Qualität der Codebasis zu verbessern. In diesem Stadium kann es jedoch riskant sein; Regressionen im bestehenden Code müssen sorgfältig vermieden werden. Refactoring when necessary
  • Kein Refactoring: Manchmal wird trotz zahlreicher Probleme in einer bestehenden Anwendung überhaupt kein Refactoring durchgeführt, weil das Management nicht in diesen Prozess investieren möchte. Das Support-Team muss dann mit dem durch Fehler und Rückmeldungen verursachten Aufwand und Stress umgehen. No refactoring

Wenn Ihr Team seine C++-Projekte regelmäßig refaktoriert und neue C++11-/C++14-Features einsetzen möchte, lohnt sich ein Blick darauf, wie bekannte C++-Projekte ihren Code für die neuen Standards modernisiert haben.

Der Chrome-Browser ist dafür ein gutes Beispiel: Seine Codebasis wird regelmäßig refaktoriert. Sobald neue Standards verabschiedet und von den Compilern unterstützt wurden, entschied sich das Chrome-Entwicklungsteam dafür, diese Standards einzusetzen.

Chrome ist ein ausgereiftes C++-Projekt. Daher ist es besonders interessant zu untersuchen, wie der Code implementiert und strukturiert ist. Schließlich wird Chrome von Millionen Menschen genutzt, was vom Entwicklungsteam entsprechend effizienten Code verlangt.

Wenn Sie Ihre C++-Codebasis refaktorieren möchten, um Features neuer Standards zu nutzen, lohnt sich ein Blick auf dieses interessante Google-Dokument. Es listet sowohl die erlaubten als auch die verbotenen C++11-/C++14-Features auf. Google document

Besonders interessant ist die Liste der verbotenen Features einschließlich der jeweiligen Begründungen. Es lohnt sich zu prüfen, ob diese Argumente auch auf Ihre eigenen Projekte zutreffen.

Hier sind die im Dokument aufgeführten verbotenen C++11-/C++14-Features:

Verbotene C++11-Features

Feature or Library Snippet Description Documentation Link Notes and Discussion Thread
Inline Namespaces inline namespace foo { ... } Allows better versioning of namespaces Inline namespaces Banned in the Google Style Guide. Unclear how it will work with components.
long long Type long long var = value; An integer of at least 64 bits Fundamental types Use a stdint.h type if you need a 64bit number. Discussion thread
Ref-qualified Member Functions class T { void f() & {} void f() && {} }; t.f();  // first T().f();  // second std::move(t).f();  // second Allows class member functions to only bind to |this| as an rvalue or lvalue. const-, volatile-, and ref-qualified member functions Banned in the Google Style Guide. May only be used in Chromium with explicit approval from styleguide/c++/OWNERSDiscussion Thread
User-Defined Literals type var = literal_value_type Allows user-defined literal expressions User-defined literals Banned in the Google Style Guide.
thread_local storage class thread_local int foo = 1; Puts variables into thread local storage. Storage duration Some surprising effects on Mac (discussionfork). Use SequenceLocalStorageSlot for sequence support, and ThreadLocal/ThreadLocalStorageotherwise.

Verbotene C++14-Features

Feature Snippet Description Documentation Link Notes and Discussion Thread
Function return type deduction auto f() { return 42; } decltype(auto) g() { return 42; } Ermöglicht es, den Rückgabetyp einer Funktion automatisch aus ihren return-Anweisungen abzuleiten, entsprechend entweder Template- oder decltype rules. Return type deduction Temporarily banned since it can cause infinite loops in clang. Wir gehen davon aus, dies zuzulassen, sobald dieser Fehler behoben ist. Die Verwendung sollte selten sein und sich hauptsächlich auf abstrakten Template-Code beschränken. Discussion thread
Generic lambdas [](const auto& x) { ... } Allows lambda argument types to be deduced using auto (according to the rules that apply to templates). lambda expressions Temporarily banned since it can cause infinite loops in clang. Wir gehen davon aus, dies zuzulassen, sobald dieser Fehler behoben ist. Discussion thread

Verbotene C++11-Bibliotheksfeatures

Feature Snippet Description Documentation Link Notes and Discussion Thread
Aligned storage std::aligned_storage<10, 128> Uninitialized storage for objects requiring specific alignment. std::aligned_storage MSVC 2017's implementation does not align on boundaries greater than sizeof(double) = 8 bytes. Use alignas(128) char foo[10]; instead. Patch where this was discovered.
Bind Operations std::bind(functionargs, ...) Declares a function object bound to certain arguments std::bind Use base::Bind instead. Compared to std::bindbase::Bind hilft, Lebensdauerprobleme zu vermeiden, indem das Binden von Capturing-Lambdas verhindert wird und Aufrufer gezwungen werden, Raw Pointer als UnretainedDiscussion thread
C Floating-Point Environment <cfenv><fenv.h> Provides floating point status flags and control modes for C-compatible code Standard library header <cfenv> Banned by the Google Style Guide due to concerns about compiler support.
Date and time utilities <chrono> A standard date and time library Date and time utilities Overlaps with Time APIs in base/. Keep using the base/ classes.
Exceptions <exception> Enhancements to exception throwing and handling Standard library header <exception> Exceptions are banned by the Google Style Guide and disabled in Chromium compiles. Note that the noexcept specifier is explicitly allowed above. Discussion thread
Function Objects std::function Wraps a standard polymorphic function std::function Use base::Callback instead. Compared to std::functionbase::Callback directly supports Chromium's refcounting classes and weak pointers and deals with additional thread safety concerns. Discussion thread
Ratio Template Class std::ratio<numeratordenominator> Provides compile-time rational numbers std::ratio Banned by the Google Style Guide aufgrund der Sorge, dass dies mit einem stärker Template-orientierten Schnittstellenstil verbunden ist.
Regular Expressions <regex> A standard regular expressions library Regular expressions library Overlaps with many regular expression libraries in Chromium. When in doubt, use re2.
Shared Pointers std::shared_ptr Allows shared ownership of a pointer through reference counts std::shared_ptr Für Chromium ist noch deutlich mehr Evaluierung erforderlich, und derzeit gibt es nicht genügend Nachfrage nach dieser Funktion. Google Style GuideDiscussion Thread
Thread Library <thread> and related headers, including <future><mutex><condition_variable> Provides a standard multithreading library using std::thread and associates Thread support library Overlaps with many classes in base/. Keep using the base/ classes for now. base::Thread is tightly coupled to MessageLoop was einen späteren Austausch erschweren würde. Wir sollten prüfen, ob sich unsere Locking-/Synchronisationsklassen durch Standard-Mutexe, unique_lock usw. ersetzen lassen.

Verbotene C++14-Bibliotheksfeatures

Dieser Abschnitt listet C++14-Bibliotheksfeatures auf, die in der Chromium-Codebasis nicht zulässig sind.

Feature Snippet Description Documentation Link Notes and Discussion Thread
std::chrono literals using namespace std::chrono_literals; auto timeout = 30s; Allows std::chrono types to be more easily constructed. std::literals::chrono_literals::operator""s Banned because <chrono> is banned.

Fazit

Den Quellcode bekannter Open-Source-Projekte zu untersuchen und ihre Design- und Implementierungsentscheidungen nachzuvollziehen, ist eine der besten Möglichkeiten, effizienten Code schreiben zu lernen. Bekannte C++-Projekte werden in der Regel von erfahrenen C++-Entwicklern gepflegt, die sich um die Anwendung bewährter Praktiken bemühen.

Kurz gesagt: Werfen Sie einen Blick auf den Chromium-Quellcode – die investierte Zeit lohnt sich.

Share this article