Freigeben über


Richtlinien für das Codieren

CNTK Codierungsformat

Auf dieser Seite werden die Konventionen dokumentiert, die im Quellcode von CNTK verwendet werden. Bitte befolgen Sie diese Konventionen beim Schreiben eines neuen Codes. Folgen Sie allgemeinem Sinn und trennen Sie Funktionen, die einen angemessenen Grenzwert überschreiten (einige Bildschirmseiten), verwenden aussagekräftige Namen, Kommentar und behalten Kommentare und Code in der Synchronisierung usw.

Grundlagen: Einzug, Abstand und Klammern

Code wird mit vier Leerzeichen konsistent eingerückt. Registerkartenzeichen sind in dem Code nicht zulässig. Die einzigen Ausnahmen sind Makefiles, ein anderes Buildsystem oder Datendateien, in denen Registerkartenzeichen syntactisch erforderlich sind.

Die folgenden Codeblöcke werden eingerückt:

  • Kontrollanweisungen: für, wenn, während, wechseln usw.
  • Kostenlose Anweisungsblöcke, d. h. Öffnen und Schließen von Klammern, die keine Steuerelement-Anweisung folgen. Diese werden manchmal verwendet, um die Lebensdauer von Objekten zu begrenzen.
  • Körper von Klassen und Funktionen.
  • Anweisungen wurden von der vorherigen Zeile fortgesetzt.
  • Code in Case-Anweisungen beginnt in der Zeile nach der Case-Anweisung und wird eingerückt.

Die folgenden Dinge werden nicht eingerückt:

  • Inhalt von Namespaces.
  • case-Bezeichnungen
  • Zugriffssteuerungsbezeichner.

Funktionsdeklarationen mit langen Parameterlisten können über mehrere Zeilen geteilt werden. Die Parameterdeklaration für die geteilten Zeilen sollte in die öffnende Klammer der Funktionsdeklaration eingerückt werden. Aufrufe von Funktionen mit langen Parameterlisten können über mehrere Zeilen aufgeteilt werden, die geteilten Zeilen sollten in die öffnende Klammer der zugeordneten Funktionsanweisung eingerückt werden.

Code wird mithilfe von Allman- oder BSD Unix-Formatklammern geschrieben. Diese Formatvorlage fügt die Klammer, die einer Steuerelement-Anweisung in der nächsten Zeile zugeordnet ist, in dieselbe Ebene wie die Steuerelement-Anweisung ein. Anweisungen innerhalb der Klammern werden auf die nächste Ebene eingerückt, es wird empfohlen, Klammern nie auszulassen, auch bei kleinen Blöcken.

Leerzeichen sind an den folgenden Stellen vorhanden:

  • Rund um alle binären Operatoren, einschließlich Zuordnungen
  • Zwischen einem Schlüsselwort und Klammern
  • Zwischen einem Bezeichner oder Schlüsselwort und einer Klammer
  • Nach Kommas und Semikolonen, die keine Zeile beenden

Leerzeichen sind an den folgenden Stellen nicht vorhanden:

  • Vor Semikolonen und Kommas
  • Auf der inneren Seite von Klammern
  • Zwischen einem Funktionsnamen und seiner Argumentliste
  • Zwischen unärlichen Operatoren und ihren Operanden
  • In einer leeren Argumentliste
  • Zwischen einer Bezeichnung und einem Doppelpunkt
  • Um den Bereichsoperator ::

Member-Initializerlisten und Basisklassenlisten, die mehrere Klassen enthalten, sollten in einer separaten Zeile geschrieben werden. Dies macht es sehr einfach, Fehler zu erkennen.

namespace Microsoft { namespace MSR { namespace CNTK {

Matrix ImplodeSelf(int x);
int ConfuseUs(float y);

class MainPart:
    public Head,
    protected Heart
{
public:
    MainPart():
        m_weight(99),
        m_height(180)
    {}
private:
    void EatMore();
    int m_consume, m_repeater;
};

template <typename Box>
void Inspect(Box & container)
{
    switch (container)
    {
    case 1:
        PrepareIt();
        break;

    case 2:
        Finish();
        break;

    default:
        break;
    }

    for (int i = 0; i < 30; ++i)
    {
        container << EatMore();
    }
    return container;
}

} } }

Benennungskonventionen

  • Klassen- und Namespacenamen verwenden UpperCamelCase aka PascalCase.
  • Namen, die häufig in all-Caps (SQL, CNTK, ...) geschrieben werden, können in allen oberen Fällen bleiben.
  • Globale und öffentliche statische Funktionen, Stapelvariablen und Klassenmitglieder (Klassenvariablen) verwenden unterCamelCase.
  • Klassenmitgliedsfunktionen (Methoden) verwenden UpperCamelCase.
  • Makros und Konstanten verwenden UPPER_SNAKE_CASE.
  • Vorlagenparameter, die Typen verwenden UpperCamelCase.
  • Typpräfixe, ungarische Notation usw. sind nicht zulässig. Verwenden Sie aussagekräftige Suffixe, wenn Sie eindeutig sein müssen, z. B. floatMatrix und normalisierteDoubleMatrix.

Namenpräfixe

  • m_ für Membervariablen
  • s_ für statische Variablen in jedem Kontext
  • g_ für globale Variablen, die an erster Stelle vermieden werden sollten (so viel wie möglich)

Variablennamen sollten Nounen sein. Funktionsnamen sollten Verben sein, mit Ausnahme von Getters, die Nounen sein können. So hätte beispielsweise eine Klasseneigenschaft namens Position den Setter SetPosition() und die getter Position().

Dateinamekonventionen

C++-Dateien sollten über die CPP-Erweiterung verfügen, während Kopfzeilendateien die H-Erweiterung aufweisen sollten. Leerzeichen und Unterstriche sind nicht zulässig. Die Verwendung von Zahlen in Dateinamen wird empfohlen.

#define GOOD_MACRO(x) x
void CallOut();
unsigned const g_theAnswer = 42;

class SolveAllProblems 
{
public:
    void DoWhatWeNeed();
    static void SetBugsOff();
    int m_countReasons;
protected:
    void NeverWorking();
    static void GetReason();
    int internalCounter;
private:
    void InternalNeeds();
    static void ShowReason();
    int m_countShows;
};

template <typename TypeParam, int numberOfReasons>
void CallGlobal(boost::array<TypeParam, numberOfReasons> const &array);

Präprozessor

Die bedingte Kompilierung mithilfe des Präprozessors wird dringend empfohlen, da es zu Coderot führt. Verwenden Sie es nur dann, wenn es unvermeidbar ist, z. B. wenn eine optionale Abhängigkeit verwendet wird. Ein Sonderfall verwendet die bedingte Kompilierung, um eine gesamte Datei basierend auf der Plattform auszuschließen, die zulässig ist.

Vor dem bedingt kompilierten, plattformspezifischen Code sollten Sie tragbaren Code schreiben, der unabhängig von der Plattform identisch ist. Die Verwendung der Boost-Bibliotheken kann in diesem Zusammenhang viel helfen. Wenn Sie je nach Plattform unterschiedliche Code verwenden müssen, versuchen Sie, sie in Hilfsfunktionen zu kapselen, sodass die Menge an Code, die sich zwischen Plattformen unterscheidet, auf einem Minimum gehalten wird.