Warum wird in diesem Array von NULL nicht negativ dekrementiert?

Lesezeit: 3 Minuten

Benutzer-Avatar
Mrsrinivas

Ich habe diesen Code ausprobiert

$a = array_fill(0, 4, NULL);
$a[0]++;
++$a[1];
$a[2]--;
--$a[3];
var_dump($a);

Ergebnis:

array(4) {
    [0]=> int(1)
    [1]=> int(1)
    [2]=> NULL
    [3]=> NULL
}

Warum ist der Wert von 2 und 3 Index nicht negativ?

  • Warum erwartest du die Index negativ werden? Das Werte Gehen Sie nicht negativ, weil NULL in PHP ist wirklich seltsam. Das hat alles mit der locker geschriebenen Natur der Sprache zu tun

    – Bojangles

    11. Juli 2013 um 11:48 Uhr

  • Das OP erwartet das nicht Index negativ sein, sondern die durch diese Indizes angegebenen Werte.

    – bemerkenswert

    11. Juli 2013 um 11:51 Uhr

  • das ist ein Kandidat für die Aufnahme auf phpsadness.com.

    – SirDarius

    11. Juli 2013 um 11:51 Uhr

  • @SirDarius Oder /r/lolphp

    – Bojangles

    11. Juli 2013 um 11:55 Uhr

Seltsam, aber dokumentiert auf der PHP-Doc-Seite Incrementing/Decrementing Operators:

Hinweis: Die Inkrement/Dekrement-Operatoren wirken sich nicht auf boolesche Werte aus. Das Dekrementieren von NULL-Werten hat ebenfalls keine Wirkung, aber das Erhöhen von Werten führt zu 1.

  • Dokumentiert -> kein Bug 😉

    – zerkms

    11. Juli 2013 um 11:53 Uhr

  • @zerkms, aber gelinde gesagt, eine ungeheuerliche Verletzung der Prinzip des geringsten Erstaunens

    – fvu

    11. Juli 2013 um 11:57 Uhr


Benutzer-Avatar
Jack

Benutze die Quelle, Luke

Wie üblich liegt die Antwort in der Quelle. PHP verwendet intern die folgenden zwei Funktionen, um die Inkrement- und Dekrementoperationen auszuführen:

ZEND_API int increment_function(zval *op1)

ZEND_API int decrement_function(zval *op1)

Diese Operationen ändern die op1 Argument basierend auf seinem Typ (NULL ist ein Typ); Innerhalb increment_function() Sie können den folgenden Zweig sehen im Code:

case IS_NULL:
    ZVAL_LONG(op1, 1);
    break;

Der obige Code ändert den Typ von op1 in eine Zahl und setzt ihren Wert auf 1.

Umgekehrt, decrement_function() bietet keine solche Filiale und daher die Standardaktion wird aufgeführt:

default:
    return FAILURE;

Das Ausführen dieses Codes führt zu keinem erkennbaren Fehler, da die Rückgabewerte in der Zend-VM absorbiert werden, aber die Variable wird definitiv auch nicht aktualisiert.

Es ist kein Fehler ™

Sie werden vielleicht überrascht sein zu wissen, dass dieses Verhalten, einschließlich des für boolesche Werte, tatsächlich so ist dokumentiert:

Notiz: Die Inkrement/Dekrement-Operatoren wirken sich nicht auf boolesche Werte aus. Dekrementieren NULL Werte hat auch keine Auswirkung, aber das Erhöhen von ihnen führt zu 1.

In Bezug auf Boolesche:

$a = true;
var_dump($a--); // true
$a = false;
var_dump($a++); // false

Apropos Saiten:

$letter="A";
var_dump(++$letter); // B
var_dump(--$letter); // B

  • Es ist kein Fehler, weil es dokumentiert ist?

    – Soz

    12. Juli 2013 um 12:54 Uhr


  • @ soz Was ist ein Softwarefehler? : Ein Softwarefehler ist ein Fehler, Fehler, Ausfall oder Fehler in einem Computerprogramm oder -system, der ein falsches oder erzeugt unerwartet Ergebnis oder bewirkt, dass es sich verhält unbeabsichtigt Wege. Aber da es dokumentiert ist, ist es ein erwartet und beabsichtigt Verhalten.

    – HamZa

    12. Juli 2013 um 14:23 Uhr

  • @soc Die leichte Ironie in diesem Teil ist vielleicht auf blinde Augen gefallen, also habe ich eine leichte Bearbeitung vorgenommen. Angesichts Ihrer früheren Beiträge zu diesem Tag bin ich jedoch überrascht, dass Sie sich zu dieser Frage hingezogen fühlen 😉

    – Jack

    12. Juli 2013 um 14:32 Uhr

  • Kommt direkt aus r/lolphp. Oh, und danke, dass du mich gestalkt und abgelehnt hast.

    – Soz

    13. Juli 2013 um 11:50 Uhr


  • @soc Ich habe mich schon immer gefragt, worum es bei reddit geht 😉 interessante Gespräche darin; Übrigens, das Stalking wurde in meinem vorherigen Kommentar veröffentlicht, ich bin mir nicht sicher, woher die Ablehnung kam.

    – Jack

    13. Juli 2013 um 15:00 Uhr

Benutzer-Avatar
Rainulf

Seltsam. Ich kenne ihren entscheidenden Faktor nicht, aber wenn ich mir das anschaue Quellcodewerden Sie sehen, dass, wenn es sich um eine NULL handelt, diese auf 1 gesetzt wird (nicht inkrementiert).

case IS_NULL:
    ZVAL_LONG(op1, 1);
    break;

Das dekrementieren Die Funktion geht überhaupt nicht mit NULL um und geht direkt zu FAILURE:

default:
    return FAILURE;

Wie andere schon erwähnt haben, ist es so dokumentiert.

Notiz: Die Inkrement/Dekrement-Operatoren wirken sich nicht auf boolesche Werte aus. Dekrementieren NULL Werte hat auch keine Auswirkung, aber das Erhöhen von ihnen führt zu 1.

1159610cookie-checkWarum wird in diesem Array von NULL nicht negativ dekrementiert?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy