Bug #53104 [Opn->Ana]: min() and max() treat NULL and BOOL differently
| From: | yohgaki@php.net | Date: | Wed, 23 Oct 2013 07:46:49 +0000 |
| Subject: | Bug #53104 [Opn->Ana]: min() and max() treat NULL and BOOL differently | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-182402@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=53104&edit=1
ID: 53104
Updated by: yohgaki@php.net
Reported by: frase at cs dot wisc dot edu
-Summary: min() and max() treat null differently
+Summary: min() and max() treat NULL and BOOL differently
-Status: Open
+Status: Analyzed
Type: Bug
-Package: Math related
+Package: Scripting Engine problem
-Operating System: Windows 2000 Pro SP4
+Operating System: any
-PHP Version: 5.3.3
+PHP Version: any
Block user comment: N
Private report: N
New Comment:
The comparison is done by compare_function() in zend_operators.c Not only NULL, but also BOOL type
also has the same problem. I haven't check fully for ARRAY, but it seems NULL and BOOL break
comparison.
We have inconsistency with comparison operators.
$ php -r "var_dump(-1 > NULL);"
bool(true)
$ php -r "var_dump(-1 < NULL);"
bool(false)
$ php -r "var_dump(min(-1,NULL));"
NULL
$ php -r "var_dump(min(NULL, -1));"
NULL
Comparison operators evaluate comparison as PHP users expect, but min() does not. This behavior is
not intuitive.
We may fix this issue or document this unexpected behavior in min() manual. (+ other functions if
there are affected)
I think this is better to be fixed even if there is BC issue at some point.
Any comments?
Test code
-----------------------------
<?php
echo "min(-1,null) = "; var_dump(min(-1,null)); echo "\n"; /* NULL */
echo "min( 1,null) = "; var_dump(min( 1,null)); echo "\n"; /* NULL */
echo "max(-1,null) = "; var_dump(max(-1,null)); echo "\n"; /* int(-1) */
echo "max( 1,null) = "; var_dump(max( 1,null)); echo "\n"; /* int(1) */
echo "min(-1,false) = "; var_dump(min(-1,null)); echo "\n"; /* NULL */
echo "min( 1,false) = "; var_dump(min( 1,null)); echo "\n"; /* NULL */
echo "max(-1,false) = "; var_dump(max(-1,null)); echo "\n"; /* int(-1) */
echo "max( 1,false) = "; var_dump(max( 1,null)); echo "\n"; /* int(1) */
echo "min(-1,true) = "; var_dump(min(-1,null)); echo "\n"; /* NULL */
echo "min( 1,true) = "; var_dump(min( 1,null)); echo "\n"; /* NULL */
echo "max(-1,true) = "; var_dump(max(-1,null)); echo "\n"; /* int(-1) */
echo "max( 1,true) = "; var_dump(max( 1,null)); echo "\n"; /* int(1) */
echo "min(null,-1) = "; var_dump(min(null,-1)); echo "\n"; /* NULL */
echo "min(null, 1) = "; var_dump(min(null, 1)); echo "\n"; /* NULL */
echo "max(null,-1) = "; var_dump(max(null,-1)); echo "\n"; /* int(-1) */
echo "max(null, 1) = "; var_dump(max(null, 1)); echo "\n"; /* int(1) */
echo "min(false,-1) = "; var_dump(min(null,-1)); echo "\n"; /* NULL */
echo "min(false, 1) = "; var_dump(min(null, 1)); echo "\n"; /* NULL */
echo "max(false,-1) = "; var_dump(max(null,-1)); echo "\n"; /* int(-1) */
echo "max(false, 1) = "; var_dump(max(null, 1)); echo "\n"; /* int(1) */
echo "min(true,-1) = "; var_dump(min(null,-1)); echo "\n"; /* NULL */
echo "min(true, 1) = "; var_dump(min(null, 1)); echo "\n"; /* NULL */
echo "max(true,-1) = "; var_dump(max(null,-1)); echo "\n"; /* int(-1) */
echo "max(true, 1) = "; var_dump(max(null, 1)); echo "\n"; /* int(1) */
echo "min(10,-1,null) = "; var_dump(min(10,-1,null)); echo "\n"; /* NULL */
echo "min(10, 1,null) = "; var_dump(min(10, 1,null)); echo "\n"; /* NULL */
echo "max(10,-1,null) = "; var_dump(max(10,-1,null)); echo "\n"; /* int(10) */
echo "max(10, 1,null) = "; var_dump(max(10, 1,null)); echo "\n"; /* int(10) */
echo "min(10,-1,false) = "; var_dump(min(10,-1,null)); echo "\n"; /* NULL */
echo "min(10, 1,false) = "; var_dump(min(10, 1,null)); echo "\n"; /* NULL */
echo "max(10,-1,false) = "; var_dump(max(10,-1,null)); echo "\n"; /* int(10) */
echo "max(10, 1,false) = "; var_dump(max(10, 1,null)); echo "\n"; /* int(10) */
echo "min(10,-1,true) = "; var_dump(min(10,-1,null)); echo "\n"; /* NULL */
echo "min(10, 1,true) = "; var_dump(min(10, 1,null)); echo "\n"; /* NULL */
echo "max(10,-1,true) = "; var_dump(max(10,-1,null)); echo "\n"; /* int(10) */
echo "max(10, 1,true) = "; var_dump(max(10, 1,null)); echo "\n"; /* int(10) */
echo "min([10,-1,null]) = "; var_dump([min(10,-1,null)]); echo "\n"; /* [NULL]
*/
echo "min([10, 1,null]) = "; var_dump([min(10, 1,null)]); echo "\n"; /* [NULL]
*/
echo "max([10,-1,null]) = "; var_dump([max(10,-1,null)]); echo "\n"; /*
[int(10)] */
echo "max([10, 1,null]) = "; var_dump([max(10, 1,null)]); echo "\n"; /*
[int(10)] */
echo "min([10,-1,false]) = "; var_dump([min(10,-1,null)]); echo "\n"; /* [NULL]
*/
echo "min([10, 1,false]) = "; var_dump([min(10, 1,null)]); echo "\n"; /* [NULL]
*/
echo "max([10,-1,false]) = "; var_dump([max(10,-1,null)]); echo "\n"; /*
[int(10)] */
echo "max([10, 1,false]) = "; var_dump([max(10, 1,null)]); echo "\n"; /*
[int(10)] */
echo "min([10,-1,true]) = "; var_dump([min(10,-1,null)]); echo "\n"; /* [NULL]
*/
echo "min([10, 1,true]) = "; var_dump([min(10, 1,null)]); echo "\n"; /* [NULL]
*/
echo "max([10,-1,true]) = "; var_dump([max(10,-1,null)]); echo "\n"; /*
[int(10)] */
echo "max([10, 1,true]) = "; var_dump([max(10, 1,null)]); echo "\n"; /*
[int(10)] */
-------------------
Previous Comments:
------------------------------------------------------------------------
[2012-04-26 20:52:28] roeitell at gmail dot com
Actually changing behavior might cause serious bc issues for some users possibly
relying on this; but attached is a patch which generates E_WARNING for min/max
receiving a NULL parameter.
------------------------------------------------------------------------
[2010-10-19 19:39:43] frase at cs dot wisc dot edu
Description:
------------
The min() and max() functions treat null values as "negative infinity", which is not
documented or (to me) particularly intuitive. I would expect null to either be treated as 0 (as
"(int)null" does), or ignore it entirely (which min() does not, but max() does by virtue
of any value being greater than negative infinity).
Test script:
---------------
echo "min(-1,null) = "; var_dump(min(-1,null)); echo "\n"; /* NULL */
echo "min( 1,null) = "; var_dump(min( 1,null)); echo "\n"; /* NULL */
echo "max(-1,null) = "; var_dump(max(-1,null)); echo "\n"; /* int(-1) */
echo "max( 1,null) = "; var_dump(max( 1,null)); echo "\n"; /* int(1) */
Expected result:
----------------
min(-1,null) = int(-1)
min( 1,null) = int(1 or 0)
max(-1,null) = int(-1 or 0)
max( 1,null) = int(1)
Actual result:
--------------
min(-1,null) = NULL
min( 1,null) = NULL
max(-1,null) = int(-1)
max( 1,null) = int(1)
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=53104&edit=1