c++ ide - Was ist der Sinn von g++-Wörter?




typeid name (5)

Erwägen:

struct A {
    int i;
    int j;
    A() : j(0), i(j) { }
};

Jetzt wird i auf einen unbekannten Wert initialisiert, nicht auf Null.

Alternativ kann die Initialisierung von i einige Nebenwirkungen haben, für die die Reihenfolge wichtig ist. Z.B

A(int n) : j(n++), i(n++) { }

Die Option g ++ -Wall enthält -Wörter. Was diese Option tut, wird im Folgenden beschrieben. Es ist mir nicht klar, wieso es jemanden interessiert (besonders genug, um dies standardmäßig in -Wall einzuschalten).

-Wreorder (C++ only)
  Warn when the order of member initializers given in the code does not
  match the order in which they must be executed.  For instance:

    struct A {
      int i;
      int j;
      A(): j (0), i (1) { }
    };

  The compiler will rearrange the member initializers for i and j to
  match the declaration order of the members, emit-ting a warning to that
  effect.  This warning is enabled by -Wall.

Andere Antworten haben einige gute Beispiele geliefert, die die Option für eine Warnung rechtfertigen. Ich dachte, ich würde einen historischen Kontext liefern. Der Entwickler von C ++, Bjarne Stroustrup, erklärt in seinem Buch Die Programmiersprache C ++ (3. Auflage, Seite 259):

Die Konstruktoren der Member werden aufgerufen, bevor der Rumpf des Konstruktors der enthaltenden Klasse ausgeführt wird. Die Konstruktoren werden in der Reihenfolge aufgerufen, in der sie in der Klasse deklariert sind, und nicht in der Reihenfolge, in der sie in der Initialisierungsliste aufgeführt sind. Um Verwirrung zu vermeiden, empfiehlt es sich, die Initialisierer in der Reihenfolge der Deklaration anzugeben. Die Elementdestruktoren werden in der umgekehrten Reihenfolge der Konstruktion aufgerufen.


Dies kann Sie beißen, wenn Ihre Initialisierer Nebenwirkungen haben. Erwägen:

int foo() {
    puts("foo");
    return 1;
}

int bar() {
    puts("bar");
    return 2;
}

struct baz {
    int x, y;
    baz() : y(foo()), x(bar()) {}
};

Das obige wird "bar" dann "foo" drucken, obwohl intuitiv angenommen wird, dass die Reihenfolge wie in der Initialisierungsliste geschrieben ist.

Wenn x und y einen benutzerdefinierten Typ mit einem Konstruktor haben, kann dieser Konstruktor auch Nebenwirkungen mit dem gleichen nicht offensichtlichen Ergebnis haben.

Es kann sich auch manifestieren, wenn der Initialisierer für ein Mitglied auf ein anderes Mitglied verweist.


Die Warnung existiert, weil, wenn Sie gerade den Konstruktor lesen, es aussieht, als ob j vor i initialisiert wird. Dies wird zu einem Problem, wenn einer verwendet wird, um den anderen zu initialisieren, wie in

struct A {
  int i;
  int j;
  A(): j (0), i (this->j) { }
};

Wenn Sie nur auf den Konstruktor schauen, sieht das sicher aus. Aber in Wirklichkeit ist j noch nicht an dem Punkt initialisiert worden, an dem es initialisiert wird, und so wird der Code nicht wie erwartet funktionieren. Daher die Warnung.


Es gibt tatsächlich einen Weg für nicht-endliche nicht-gewerkschaftliche Klassentypen:

namespace detail {
    struct P {typedef int member;};
    template <typename U>
    struct test_for_member : U, P
    {
        template <typename T=test_for_member, typename = typename T::member>
        static std::false_type test(int);
        static std::true_type test(float);
    };
}
template <typename T>
using test_for_member =
  std::integral_constant<bool, decltype(detail::test_for_member<T>::test(0)){}>;

Demo . Der Trick besteht darin, zu prüfen, ob das Nachschlagen in verschiedene Basisklassen eine Mehrdeutigkeit ergibt. [class.member.lookup] / 2:

Die Suche nach Mitgliedsnamen bestimmt die Bedeutung eines Namens ( ID-Ausdruck ) in einem Klassenbereich (3.3.7). Namens-Nachschlagen kann zu einer Mehrdeutigkeit führen , in welchem ​​Fall das Programm schlecht ausgebildet ist. [...] Die Namenssuche findet vor der Zugriffskontrolle statt (3.4, Abschnitt 11).

Beachten Sie, dass die Suche nach GCCs insofern fehlerhaft ist, als sie Nicht-Typ-Namen für die Suche in Typname-Spezifizierer ignoriert.







c++ g++ compiler-warnings