Suche…


Syntax

  • [[Details]]: Einfaches Argument ohne Argument

  • [[Details (Argumente)]]: Attribut mit Argumenten

  • __attribute (Details): Nicht GCC / Clang / IBM-spezifisch

  • __declspec (Details): Nicht-Standard MSVC-spezifisch

[[keine Rückkehr]]

C ++ 11

In C ++ 11 wurde das Attribut [[noreturn]] . Es kann für eine Funktion verwendet werden, um anzuzeigen, dass die Funktion nicht zum Aufrufer zurückkehrt, indem entweder eine return- Anweisung ausgeführt wird oder das Ende des Textes erreicht wird (es ist wichtig zu beachten, dass dies nicht für void Funktionen gilt, da sie dies sind) kehren Sie zum Anrufer zurück, sie geben nur keinen Wert zurück. Eine solche Funktion kann mit dem Aufruf von std::terminate oder std::exit oder mit dem Auslösen einer Ausnahme std::terminate . Es ist auch erwähnenswert, dass eine solche Funktion durch Ausführen von longjmp .

Die folgende Funktion [[noreturn]] zum Beispiel immer eine Ausnahme aus oder ruft std::terminate , daher ist sie ein guter Kandidat für [[noreturn]] :

[[noreturn]] void ownAssertFailureHandler(std::string message) {
    std::cerr << message << std::endl;
    if (THROW_EXCEPTION_ON_ASSERT)
        throw AssertException(std::move(message));
    std::terminate();
}

Durch diese Art von Funktionalität kann der Compiler eine Funktion ohne return-Anweisung beenden, wenn er weiß, dass der Code niemals ausgeführt wird. Da der Aufruf von ownAssertFailureHandler (oben definiert) im nachstehenden Code niemals zurückgegeben wird, muss der Compiler hier keinen Code unter diesem Aufruf hinzufügen:

std::vector<int> createSequence(int end) {
    if (end > 0) {
        std::vector<int> sequence;
        sequence.reserve(end+1);
        for (int i = 0; i <= end; ++i)
            sequence.push_back(i);
        return sequence;
    }
    ownAssertFailureHandler("Negative number passed to createSequence()"s);
    // return std::vector<int>{}; //< Not needed because of [[noreturn]]
}

Es ist undefiniertes Verhalten, wenn die Funktion tatsächlich zurückkehrt. Folgendes ist nicht zulässig:

[[noreturn]] void assertPositive(int number) {
    if (number >= 0)
        return;
    else
        ownAssertFailureHandler("Positive number expected"s); //< [[noreturn]]
}

Beachten Sie, dass der [[noreturn]] meist in void-Funktionen verwendet wird. Dies ist jedoch keine Voraussetzung, damit die Funktionen in der generischen Programmierung verwendet werden können:

template<class InconsistencyHandler>
double fortyTwoDivideBy(int i) {
    if (i == 0)
         i = InconsistencyHandler::correct(i);
    return 42. / i;
}

struct InconsistencyThrower {
    static [[noreturn]] int correct(int i) { ownAssertFailureHandler("Unknown inconsistency"s); }
}

struct InconsistencyChangeToOne {
    static int correct(int i) { return 1; }
}

double fortyTwo = fortyTwoDivideBy<InconsistencyChangeToOne>(0);
double unreachable = fortyTwoDivideBy<InconsistencyThrower>(0);

Die folgenden Standardbibliotheksfunktionen haben dieses Attribut:

  • std :: abbrechen
  • std :: exit
  • std :: quick_exit
  • std :: unerwartet
  • std :: terminate
  • std :: rethrow_exception
  • std :: throw_with_nested
  • std :: nested_exception :: rethrow_nested

[[durchfallen]]

C ++ 17

Wenn ein case in einem switch , wird der Code des nächsten Falls ausgeführt. Letzteres kann mit der ´break'-Anweisung verhindert werden. Da dieses sogenannte Fallthrough-Verhalten zu Fehlern führen kann, wenn dies nicht beabsichtigt ist, warnen mehrere Compiler und statische Analysatoren dies.

Ab C ++ 17 wurde ein Standardattribut eingeführt, um anzuzeigen, dass die Warnung nicht erforderlich ist, wenn der Code durchfallen soll. Compiler können sicher [[fallthrough]] wenn ein Fall ohne break oder [[fallthrough]] und mindestens eine Anweisung [[fallthrough]] .

switch(input) {
    case 2011:
    case 2014:
    case 2017:
        std::cout << "Using modern C++" << std::endl;
        [[fallthrough]]; // > No warning
    case 1998:
    case 2003:
        standard = input;
}

In dem Vorschlag finden Sie detailliertere Beispiele, wie [[fallthrough]] verwendet werden kann.

[[veraltet]] und [[veraltet ("Grund")]]

C ++ 14

Mit C ++ 14 wurde eine Standardmethode eingeführt, um Funktionen über Attribute abzulehnen. [[deprecated]] kann verwendet werden, um anzuzeigen, dass eine Funktion veraltet ist. [[deprecated("reason")]] ermöglicht das Hinzufügen eines bestimmten Grunds, der vom Compiler angezeigt werden kann.

void function(std::unique_ptr<A> &&a);

// Provides specific message which helps other programmers fixing there code
[[deprecated("Use the variant with unique_ptr instead, this function will be removed in the next release")]]
void function(std::auto_ptr<A> a);

// No message, will result in generic warning if called.
[[deprecated]]
void function(A *a);

Dieses Attribut kann angewendet werden auf:

  • die Deklaration einer Klasse
  • ein typedef-name
  • eine Variable
  • ein nicht statisches Datenelement
  • eine Funktion
  • eine Aufzählung
  • eine Vorlagenspezialisierung

(Ref. C ++ 14 Standardentwurf : 7.6.5 Veraltetes Attribut)

[nodiscard]]

C ++ 17

Das Attribut [[nodiscard]] kann verwendet werden, um anzuzeigen, dass der Rückgabewert einer Funktion beim Funktionsaufruf nicht ignoriert werden soll. Wenn der Rückgabewert ignoriert wird, sollte der Compiler eine Warnung ausgeben. Das Attribut kann hinzugefügt werden:

  • Eine Funktionsdefinition
  • Eine Art

Das Hinzufügen des Attributs zu einem Typ hat dasselbe Verhalten wie das Hinzufügen des Attributs zu jeder einzelnen Funktion, die diesen Typ zurückgibt.

template<typename Function>
[[nodiscard]] Finally<std::decay_t<Function>> onExit(Function &&f);

void f(int &i) {
    assert(i == 0);                    // Just to make comments clear!
    ++i;                               // i == 1
    auto exit1 = onExit([&i]{ --i; }); // Reduce by 1 on exiting f()
    ++i;                               // i == 2
    onExit([&i]{ --i; });              // BUG: Reducing by 1 directly
                                       //      Compiler warning expected
    std::cout << i << std::end;        // Expected: 2, Real: 1
}

Siehe den Vorschlag für detailliertere Beispiele, wie [[nodiscard]] verwendet werden kann.

Hinweis: Die Details der Implementierung Finally / onExit sind in dem Beispiel weggelassen, siehe Schließlich / ScopeExit .

[[vielleicht_unused]]

Das Attribut [[maybe_unused]] wird erstellt, um im Code [[maybe_unused]] dass bestimmte Logik möglicherweise nicht verwendet wird. Dies wird häufig mit Präprozessor-Bedingungen verknüpft, bei denen dies verwendet werden kann oder nicht verwendet werden kann. Da Compiler zu nicht verwendeten Variablen Warnungen ausgeben können, können sie auf diese Weise durch Angabe von Absichten unterdrückt werden.

Ein typisches Beispiel für Variablen, die in Debugbuilds benötigt werden, während sie in der Produktion nicht benötigt werden, sind Rückgabewerte, die den Erfolg anzeigen. In den Debug-Builds sollte die Bedingung geltend gemacht werden, obwohl diese Assays in der Produktion entfernt wurden.

[[maybe_unused]] auto mapInsertResult = configuration.emplace("LicenseInfo", stringifiedLicenseInfo);
assert(mapInsertResult.second); // We only get called during startup, so we can't be in the map

Ein komplexeres Beispiel sind verschiedene Arten von Hilfsfunktionen, die sich in einem unbenannten Namensraum befinden. Wenn diese Funktionen beim Kompilieren nicht verwendet werden, gibt der Compiler möglicherweise eine Warnung aus. Im Idealfall möchten Sie sie mit den gleichen Präprozessor-Tags wie der Aufrufer [[maybe_unused]] dies jedoch komplex werden kann, ist das Attribut [[maybe_unused]] eine eher wartbare Alternative.

namespace {
    [[maybe_unused]] std::string createWindowsConfigFilePath(const std::string &relativePath);
    // TODO: Reuse this on BSD, MAC ...
    [[maybe_unused]] std::string createLinuxConfigFilePath(const std::string &relativePath);
}

std::string createConfigFilePath(const std::string &relativePath) {
#if OS == "WINDOWS"
      return createWindowsConfigFilePath(relativePath);
#elif OS == "LINUX"
      return createLinuxConfigFilePath(relativePath);
#else
#error "OS is not yet supported"
#endif
}

In dem Vorschlag finden Sie detailliertere Beispiele zur Verwendung von [[maybe_unused]] .



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow