Was ist der Vorteil einer Beendigung, wenn ... sonst wenn Konstrukte mit einer else-Klausel erstellt werden?


136

Unsere Organisation hat eine erforderliche Codierungsregel (ohne Erklärung), die:

if… else if Konstrukte sollten mit einer else-Klausel beendet werden

Beispiel 1:

if ( x < 0 )
{
   x = 0;
} /* else not needed */

Beispiel 2:

if ( x < 0 )
{
    x = 0;
}
else if ( y < 0 )
{
    x = 3;
}
else    /* this else clause is required, even if the */
{       /* programmer expects this will never be reached */
        /* no change in value of x */
}

Für welchen Randfall ist dies ausgelegt?

Was mich auch über den Grund beunruhigt, ist, dass Beispiel 1 kein benötigt else, Beispiel 2 jedoch. Wenn der Grund die Wiederverwendbarkeit und Erweiterbarkeit ist, sollte meiner Meinung elsenach in beiden Fällen verwendet werden.


30
Fragen Sie vielleicht Ihr Unternehmen nach dem Grund und dem Nutzen. Auf den ersten Blick zwingt es den Programmierer, darüber nachzudenken und einen Kommentar "Keine Aktion erforderlich" hinzuzufügen. Gleiche Argumentation hinter (und mindestens so kontrovers wie) Javas geprüften Ausnahmen.
Thilo

32
Beispiel 2 ist eigentlich ein gutes Beispiel dafür, wo ein assert(false, "should never go here")Sinn machen könnte
Thilo

2
Unsere Organisation hat ähnliche Regeln, aber nicht ganz so detailliert. Der Zweck in unserem Fall ist zweifach. Erstens die Codekonsistenz. Zweitens keine losen Zeichenfolgen / Lesbarkeit. Wenn Sie das else auch dann benötigen, wenn es nicht benötigt wird, wird der Code klarer, auch wenn er nicht dokumentiert ist. Das Erfordernis eines anderen ist etwas, was ich in der Vergangenheit getan habe, auch wenn es nicht benötigt wird, nur um sicherzustellen, dass ich alle möglichen Ergebnisse in der App berücksichtigt habe.
LuvnJesus

4
Sie könnten immer besiegen, wenn mit if (x < 0) { x = 0; } else { if (y < 0) { x = 3; }}. Oder Sie könnten einfach solchen Regeln folgen, von denen viele dumm sind, einfach weil Sie dazu verpflichtet sind.
Jim Balter

3
@Thilo Ich bin ein bisschen spät dran, aber immer noch hat niemand den Fehler bemerkt: Es gibt keinen Hinweis darauf, dass das andere niemals passieren sollte, nur dass es keine Nebenwirkungen haben sollte (was bei < 0Überprüfungen normal erscheint ), so dass die Behauptung geht um das Programm in dem wahrscheinlich häufigsten Fall zum Absturz zu bringen, in dem Werte in erwarteten Grenzen liegen.
Loduwijk

Antworten:


148

Wie in einer anderen Antwort erwähnt, stammt dies aus den MISRA-C-Codierungsrichtlinien. Der Zweck ist die defensive Programmierung, ein Konzept, das häufig in der geschäftskritischen Programmierung verwendet wird.

Das heißt, jeder if - else ifmuss mit einem enden elseund jeder switchmuss mit einem enden default.

Dafür gibt es zwei Gründe:

  • Selbstdokumentierender Code. Wenn Sie ein schreiben else, es aber leer lassen, bedeutet dies: "Ich habe das Szenario definitiv in Betracht gezogen, in dem weder ifnoch else ifwahr sind".

    Dort nicht zu schreiben elsebedeutet: "Entweder habe ich das Szenario in Betracht gezogen, in dem weder ifnoch else ifwahr sind, oder ich habe völlig vergessen, es zu berücksichtigen, und hier in meinem Code befindet sich möglicherweise ein fetter Fehler."

  • Stoppen Sie den außer Kontrolle geratenen Code. In unternehmenskritischer Software müssen Sie robuste Programme schreiben, die selbst das höchst Unwahrscheinliche berücksichtigen. So konnte man Code wie sehen

    if (mybool == TRUE) 
    {
    } 
    else if (mybool == FALSE) 
    {
    }
    else
    {
      // handle error
    }

    Dieser Code ist PC-Programmierern und Informatikern völlig fremd, macht aber in unternehmenskritischer Software durchaus Sinn, da er den Fall erfasst, in dem der "mybool" aus irgendeinem Grund beschädigt wurde.

    In der Vergangenheit würden Sie eine Beschädigung des RAM-Speichers aufgrund von EMI / Rauschen befürchten. Dies ist heute kein großes Problem. Es ist weitaus wahrscheinlicher, dass Speicherbeschädigungen aufgrund von Fehlern an anderer Stelle im Code auftreten: Zeiger auf falsche Speicherorte, Fehler außerhalb des Bereichs, Stapelüberlauf, außer Kontrolle geratener Code usw.

    In den meisten Fällen kommt Code wie dieser zurück, um sich selbst ins Gesicht zu schlagen, wenn Sie während der Implementierungsphase Fehler geschrieben haben. Das heißt, es kann auch als Debug-Technik verwendet werden: Das Programm, das Sie schreiben, teilt Ihnen mit, wann Sie Fehler geschrieben haben.


BEARBEITEN

In Bezug darauf, warum elsenicht nach jedem einzelnen benötigt wird if:

Ein if-elseoder if-else if-elsedeckt alle möglichen Werte ab, die eine Variable haben kann. Eine einfache ifAussage ist jedoch nicht unbedingt dazu da, alle möglichen Werte abzudecken, sondern wird viel breiter verwendet. Meistens möchten Sie nur eine bestimmte Bedingung überprüfen, und wenn sie nicht erfüllt ist, tun Sie nichts. Dann ist es einfach nicht sinnvoll, defensive Programme zu schreiben, um den elseFall abzudecken .

Außerdem würde es den Code komplett überladen, wenn Sie elsenach jedem einen leeren Code schreiben würden if.

MISRA-C: 2012 15.7 gibt keine Begründung, warum elsees nicht benötigt wird, es heißt nur:

Hinweis: elseFür eine einfache if Anweisung ist keine abschließende Aussage erforderlich .


6
Wenn der Speicher beschädigt ist, erwarte ich, dass er viel mehr als nur mybool zerstört, einschließlich möglicherweise des Prüfcodes selbst. Warum fügen Sie keinen weiteren Block hinzu, der überprüft, ob Sie das if/else if/elsekompiliert haben, was Sie erwarten? Und dann noch eine, um auch den vorherigen Prüfer zu überprüfen?
Oleg V. Volkov

49
Seufzer. Leute, wenn Sie absolut keine andere Erfahrung als die Desktop-Programmierung haben, müssen Sie keine Besserwisser-Kommentare zu etwas abgeben, mit dem Sie offensichtlich keine Erfahrung haben. Dies geschieht immer dann, wenn die defensive Programmierung besprochen wird und ein PC-Programmierer vorbeischaut. Ich habe aus einem bestimmten Grund den Kommentar "Dieser Code ist PC-Programmierern völlig fremd" hinzugefügt. Sie programmieren keine sicherheitskritische Software für die Ausführung auf RAM-basierten Desktop-Computern . Zeitraum. Der Code selbst befindet sich im Flash-ROM mit ECC- und / oder CRC-Prüfsummen.
Lundin

6
@Deduplicator In der Tat (es sei denn, es handelt myboolsich um einen nicht-booleschen Typ, wie dies vor C der Fall war bool; dann würde der Compiler die Annahme ohne zusätzliche statische Analyse nicht treffen). Und zum Thema "Wenn Sie ein anderes schreiben, es aber leer lassen, bedeutet dies:" Ich habe das Szenario definitiv in Betracht gezogen, wenn weder wenn noch sonst wahr ist ". Meine erste Reaktion ist die Annahme, dass der Programmierer vergessen hat, Code einzugeben der else-Block, sonst warum nur ein leerer else-Block da sitzen? Ein // unusedKommentar wäre angebracht, nicht nur ein leerer Block.
JAB

5
@JAB Ja, der elseBlock muss einen Kommentar enthalten, wenn kein Code vorhanden ist. Übliche Praxis für leer elseist ein einzelnes Semikolon plus ein Kommentar : else { ; // doesn't matter }. Da es keinen Grund gibt, warum jemand sonst einfach ein eingerücktes, einzelnes Semikolon in einer eigenen Zeile eingeben würde. Eine ähnliche Vorgehensweise wird manchmal in leeren Schleifen angewendet : while(something) { ; // do nothing }. (Code mit Zeilenumbrüchen natürlich. SO Kommentare erlauben sie nicht)
Lundin

5
Ich möchte darauf hinweisen, dass dieser Beispielcode mit zwei IFs und auch in gewöhnlicher Desktop-Software in Multithread-Umgebungen zu anderen verwendet werden kann, sodass der Wert von mybool nur zwischendurch geändert werden kann
Iłya Bursov

61

Ihr Unternehmen hat die MISRA-Codierungsrichtlinien befolgt. Es gibt einige Versionen dieser Richtlinien, die diese Regel enthalten, jedoch aus MISRA-C: 2004 :

Regel 14.10 (erforderlich): Alle if… else if-Konstrukte sollen mit einer else-Klausel beendet werden.

Diese Regel gilt immer dann, wenn auf eine if-Anweisung eine oder mehrere if-Anweisungen folgen. Auf das letzte andere iffolgt eine else Erklärung. Im Falle einer einfachen ifAnweisung muss die else Anweisung nicht enthalten sein. Voraussetzung für eine Abschlusserklärung else ist die defensive Programmierung. Die elseErklärung muss entweder geeignete Maßnahmen ergreifen oder einen geeigneten Kommentar dazu enthalten, warum keine Maßnahmen ergriffen werden. Dies steht im Einklang mit der Anforderung, eine Schlussklausel defaultin einer switchErklärung zu haben. Zum Beispiel ist dieser Code eine einfache if-Anweisung:

if ( x < 0 )
{
 log_error(3);
 x = 0;
} /* else not needed */

während der folgende Code zeigt ein if, else ifKonstrukt

if ( x < 0 )
{
 log_error(3);
 x = 0;
}
else if ( y < 0 )
{
 x = 3;
}
else /* this else clause is required, even if the */
{ /* programmer expects this will never be reached */
 /* no change in value of x */
}

In MISRA-C: 2012 , das die Version 2004 ersetzt und die aktuelle Empfehlung für neue Projekte darstellt, existiert dieselbe Regel, ist jedoch mit 15,7 nummeriert .

Beispiel 1: In einer einzelnen if-Anweisung muss der Programmierer möglicherweise n Bedingungen überprüfen und führt eine einzelne Operation aus.

if(condition_1 || condition_2 || ... condition_n)
{
   //operation_1
}

Bei einer normalen Verwendung ist die Ausführung einer Operation nicht immer erforderlich, wenn sie ifverwendet wird.

Beispiel 2: Hier prüft der Programmierer n Anzahl von Bedingungen und führt mehrere Operationen aus. In regelmäßiger Anwendung if..else ifist wie switchSie eine Operation wie Standard ausführen müssen können. Daher elseist eine Verwendung gemäß Misra-Standard erforderlich

if(condition_1 || condition_2 || ... condition_n)
{
   //operation_1
}
else if(condition_1 || condition_2 || ... condition_n)
{
  //operation_2
}
....
else
{
   //default cause
}

Aktuelle und frühere Versionen dieser Veröffentlichungen können über den MISRA-Webstore ( via ) erworben werden.


1
Vielen Dank, Ihre Antwort ist der gesamte Inhalt der Misra-Regel, aber ich erwarte eine Antwort für meine Verwirrung beim Bearbeiten eines Teils der Frage.
Trevor

2
Gute Antwort. Sagen diese Führer aus Neugier etwas darüber, was zu tun ist, wenn Sie erwarten, dass die elseKlausel nicht erreichbar ist? (Lassen Sie stattdessen die endgültige Bedingung weg, werfen Sie vielleicht einen Fehler?)
jpmc26

17
Ich werde für Plagiate und Links, die das Urheberrecht verletzen, abstimmen. Ich werde den Beitrag so bearbeiten, dass klarer wird, was Ihre Worte und was MISRAs Worte sind. Anfangs war diese Antwort nichts anderes als ein rohes Kopieren / Einfügen.
Lundin

8
@TrieuTheVan: Fragen dürfen keine beweglichen Ziele sein . Stellen Sie sicher, dass Ihre Frage vollständig ist, bevor Sie sie veröffentlichen.
TJ Crowder

1
@ jpmc26 Nein, aber der Sinn von MISRA ist nicht, Ihnen engen Code zu geben, sondern Ihnen sicheren Code zu geben. Jeder Compiler optimiert heutzutage ohnehin nicht erreichbaren Code, sodass es keinen Nachteil gibt.
Graham

19

Dies entspricht der Anforderung eines Standardfalls für jeden Switch.

Dieses Extra verringert die Codeabdeckung Ihres Programms.


Nach meiner Erfahrung mit der Portierung von Linux-Kernel oder Android-Code auf eine andere Plattform machen wir oft etwas falsch und in logcat sehen wir einige Fehler wie

if ( x < 0 )
{
    x = 0;
}
else if ( y < 0 )
{
    x = 3;
}
else    /* this else clause is required, even if the */
{       /* programmer expects this will never be reached */
        /* no change in value of x */
        printk(" \n [function or module name]: this should never happen \n");

        /* It is always good to mention function/module name with the 
           logs. If you end up with "this should never happen" message
           and the same message is used in many places in the software
           it will be hard to track/debug.
        */
}

2
Dies ist , wo __FILE__und __LINE__Makros sind nützlich , um den Quellort leicht zu finden , wenn die Nachricht gedruckt wird eh und je.
Peter Cordes

9

Nur eine kurze Erklärung, da ich das alles vor ungefähr 5 Jahren gemacht habe.

Es gibt (bei den meisten Sprachen) keine syntaktische Anforderung, die elseAnweisung "null" (und unnötig {..}) einzuschließen , und in "einfachen kleinen Programmen" besteht keine Notwendigkeit. Aber echte Programmierer schreiben keine "einfachen kleinen Programme", und ebenso wichtig ist, dass sie keine Programme schreiben, die einmal verwendet und dann verworfen werden.

Wenn man ein if / else schreibt:

if(something)
  doSomething;
else
  doSomethingElse;

es scheint alles einfach und man sieht kaum den Sinn des Hinzufügens {..}.

Aber eines Tages, in einigen Monaten, muss ein anderer Programmierer (Sie würden niemals einen solchen Fehler machen!) Das Programm "verbessern" und eine Erklärung hinzufügen.

if(something)
  doSomething;
else
  doSomethingIForgot;
  doSomethingElse;

Plötzlich doSomethingElsevergisst irgendwie, dass es im elseBein sein soll.

Sie sind also ein guter kleiner Programmierer und verwenden immer {..}. Aber du schreibst:

if(something) {
  if(anotherThing) {
    doSomething;
  }
}

Alles ist gut und schön, bis dieses neue Kind eine Mitternachtsmodifikation vornimmt:

if(something) {
  if(!notMyThing) {
  if(anotherThing) {
    doSomething;
  }
  else {
    dontDoAnything;  // Because it's not my thing.
  }}
}

Ja, es ist falsch formatiert, aber auch der halbe Code im Projekt, und der "automatische Formatierer" wird durch alle #ifdefAnweisungen durcheinander gebracht . Und natürlich ist der echte Code weitaus komplizierter als dieses Spielzeugbeispiel.

Leider (oder auch nicht) bin ich seit ein paar Jahren nicht mehr in der Lage, also habe ich kein neues "echtes" Beispiel im Sinn - das oben Genannte ist (offensichtlich) erfunden und ein bisschen hokey.


7

Dies geschieht, um den Code für spätere Verweise besser lesbar zu machen und einem späteren Prüfer klar zu machen, dass die verbleibenden Fälle, die vom letzten behandelt werden else, keine Fälle sind, damit sie auf den ersten Blick nicht übersehen werden.

Dies ist eine gute Programmierpraxis, die Code wiederverwendbar und erweiterbar macht .


6

Ich möchte die vorherigen Antworten ergänzen - und teilweise widersprechen. Während es sicherlich üblich ist, if-else zu verwenden, wenn es sich um einen Schalter handelt, der den gesamten Bereich denkbarer Werte für einen Ausdruck abdecken soll, ist keineswegs garantiert, dass ein Bereich möglicher Bedingungen vollständig abgedeckt ist. Das Gleiche gilt für das Switch-Konstrukt selbst, daher die Anforderung, eine Standardklausel zu verwenden, die alle verbleibenden Werte abfängt und, sofern dies nicht anderweitig erforderlich ist, als Assertionsschutz verwendet werden kann.

Die Frage selbst enthält ein gutes Gegenbeispiel: Die zweite Bedingung bezieht sich überhaupt nicht auf x (weshalb ich häufig die flexiblere if-basierte Variante der switchbasierten Variante vorziehe). Aus dem Beispiel geht hervor, dass x auf einen bestimmten Wert gesetzt werden sollte, wenn die Bedingung A erfüllt ist. Sollte A nicht erfüllt sein, wird Bedingung B getestet. Wenn es erfüllt ist, sollte x einen anderen Wert erhalten. Wenn weder A noch B erfüllt sind, sollte x unverändert bleiben.

Hier können wir sehen, dass ein leerer else-Zweig verwendet werden sollte, um die Absicht des Programmierers für den Leser zu kommentieren.

Andererseits kann ich nicht verstehen, warum es eine else-Klausel speziell für die neueste und innerste if-Anweisung geben muss. In C gibt es kein "else if". Es gibt nur wenn und sonst. Stattdessen sollte laut MISRA das Konstrukt auf diese Weise formal eingerückt werden (und ich hätte die öffnenden geschweiften Klammern auf ihre eigenen Linien setzen sollen, aber das gefällt mir nicht):

if (A) {
    // do something
}
else {
    if (B) {
        // do something else (no pun intended)
    }
    else {
        // don't do anything here
    }
}

Wenn MISRA darum bittet, geschweifte Klammern um jeden Zweig zu setzen, widerspricht es sich selbst, indem es "wenn ... sonst wenn Konstrukte" erwähnt.

Jeder kann sich die Hässlichkeit tief verschachtelter Bäume vorstellen, siehe hier eine Randnotiz . Stellen Sie sich nun vor, dass dieses Konstrukt beliebig überall erweitert werden kann. Dann wird es absurd, am Ende nach einer else-Klausel zu fragen, aber nirgendwo anders.

if (A) {
    if (B) {
        // do something
    }
    // you could to something here
}
else {
    // or here
    if (B) { // or C?
        // do something else (no pun intended)
    }
    else {
        // don't do anything here, if you don't want to
    }
    // what if I wanted to do something here? I need brackets for that.
}

Ich bin mir also sicher, dass die Leute, die die MISRA-Richtlinien entwickelt haben, das switch-like if-else-beabsichtigte Ziel hatten.

Am Ende kommt es darauf an, genau zu definieren, was mit einem "wenn ... sonst wenn Konstrukt" gemeint ist.


5

Der Hauptgrund ist wahrscheinlich die Codeabdeckung und das implizite andere: Wie verhält sich der Code, wenn die Bedingung nicht erfüllt ist? Für echte Tests benötigen Sie eine Möglichkeit, um festzustellen, ob Sie mit der Bedingung false getestet haben. Wenn jeder Testfall, den Sie haben, die if-Klausel durchläuft, kann Ihr Code aufgrund einer Bedingung, die Sie nicht getestet haben, Probleme in der realen Welt haben.

Einige Bedingungen können jedoch ordnungsgemäß wie in Beispiel 1 sein, z. B. in einer Steuererklärung: "Wenn das Ergebnis kleiner als 0 ist, geben Sie 0 ein." Sie müssen noch einen Test durchführen, bei dem die Bedingung falsch ist.


5

Logischerweise impliziert jeder Test zwei Zweige. Was machst du, wenn es wahr ist, und was machst du, wenn es falsch ist?

In den Fällen, in denen einer der Zweige keine Funktionalität hat, ist es sinnvoll, einen Kommentar hinzuzufügen, warum er keine Funktionalität benötigt.

Dies kann für den nächsten Wartungsprogrammierer von Vorteil sein. Sie sollten nicht zu weit suchen müssen, um zu entscheiden, ob der Code korrekt ist. Sie können den Elefanten irgendwie vorjagen .

Persönlich hilft es mir, da es mich zwingt, den anderen Fall zu betrachten und ihn zu bewerten. Es kann eine unmögliche Bedingung sein. In diesem Fall kann ich eine Ausnahme auslösen, da der Vertrag verletzt wird. Es kann harmlos sein. In diesem Fall kann ein Kommentar ausreichen.

Ihr Kilometerstand kann variieren.


4

Die meiste Zeit, wenn Sie nur eine einzige ifAussage haben, ist dies wahrscheinlich einer der Gründe wie:

  • Funktionsschutzprüfungen
  • Initialisierungsoption
  • Optionaler Verarbeitungszweig

Beispiel

void print (char * text)
{
    if (text == null) return; // guard check

    printf(text);
}

Aber wenn Sie dies tun if .. else if, ist dies wahrscheinlich einer der Gründe wie:

  • Dynamisches Schaltgehäuse
  • Bearbeitungsgabel
  • Behandlung eines Verarbeitungsparameters

Und falls Ihr if .. else ifalle Möglichkeiten abdeckt, in diesem Fall Ihr letzter if (...)nicht benötigt wird, können Sie ihn einfach entfernen, da zu diesem Zeitpunkt die einzig möglichen Werte diejenigen sind, die von dieser Bedingung abgedeckt werden.

Beispiel

int absolute_value (int n)
{
    if (n == 0)
    {
        return 0;
    }
    else if (n > 0)
    {
        return n;
    }
    else /* if (n < 0) */ // redundant check
    {
        return (n * (-1));
    }
}

Und in den meisten dieser Gründe ist es möglich, dass etwas in keine der Kategorien in Ihrer Kategorie passt. if .. else ifDaher muss es in einer abschließenden elseKlausel behandelt werden. Die Behandlung kann über Verfahren auf Unternehmensebene, Benutzerbenachrichtigung, internen Fehlermechanismus erfolgen. ..etc.

Beispiel

#DEFINE SQRT_TWO   1.41421356237309504880
#DEFINE SQRT_THREE 1.73205080756887729352
#DEFINE SQRT_FIVE  2.23606797749978969641

double square_root (int n)
{
         if (n  > 5)   return sqrt((double)n);
    else if (n == 5)   return SQRT_FIVE;
    else if (n == 4)   return 2.0;
    else if (n == 3)   return SQRT_THREE;
    else if (n == 2)   return SQRT_TWO;
    else if (n == 1)   return 1.0;
    else if (n == 0)   return 0.0;
    else               return sqrt(-1); // error handling
}

Diese letzte elseKlausel ähnelt einigen anderen Dingen in Sprachen wie Javaund C++, wie zum Beispiel:

  • default Fall in einer switch-Anweisung
  • catch(...)das kommt nach allen spezifischen catchBlöcken
  • finally in einer try-catch-Klausel

2

Unsere Software war nicht geschäftskritisch, aber wir haben uns aufgrund der defensiven Programmierung auch für diese Regel entschieden. Wir haben dem theoretisch nicht erreichbaren Code eine Wurfausnahme hinzugefügt (switch + if-else). Und es hat uns viele Male gerettet, da die Software schnell fehlgeschlagen ist, z. B. wenn ein neuer Typ hinzugefügt wurde und wir vergessen haben, ein oder zwei if-else oder switch zu ändern. Als Bonus war es super einfach, das Problem zu finden.


2

Nun, mein Beispiel beinhaltet undefiniertes Verhalten, aber manchmal versuchen einige Leute, ausgefallen zu sein und scheitern schwer. Schauen Sie sich das an:

int a = 0;
bool b = true;
uint8_t* bPtr = (uint8_t*)&b;
*bPtr = 0xCC;
if(b == true)
{
    a += 3;
}
else if(b == false)
{
    a += 5;
}
else
{
    exit(3);
}

Sie würden wahrscheinlich nie erwarten zu haben , boolwas nicht ist , truenoch false, aber es kann passieren. Persönlich glaube ich, dass dies ein Problem ist, das von einer Person verursacht wird, die sich entscheidet, etwas Besonderes zu tun, aber eine zusätzliche elseAussage kann weitere Probleme verhindern.


1

Ich arbeite derzeit mit PHP. Erstellen eines Registrierungsformulars und eines Anmeldeformulars. Ich benutze nur wenn und sonst. Nichts anderes, wenn oder irgendetwas, was unnötig ist.

Wenn der Benutzer auf die Schaltfläche "Senden" klickt -> wird mit der nächsten if-Anweisung fortgefahren ... Wenn der Benutzername weniger als "X" Zeichen enthält, wird eine Warnung ausgegeben. Wenn erfolgreich, überprüfen Sie die Passwortlänge und so weiter.

Es ist kein zusätzlicher Code erforderlich, z. B. ein anderer, wenn dies die Zuverlässigkeit der Serverladezeit beeinträchtigen könnte, um den gesamten zusätzlichen Code zu überprüfen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.