Last july Gustavo (cataphract@) committed
980dc7111bc1d1e759c5b6044f6e7d203915d81f "zend_parse_parameters: allow
! for non pointers" which is awesome, but it creates a difference in
behavior between pointer and non-pointer types when used with the '!'
modifier. So before 5.5 hits freeze, I'd like to consider modifying
it to keep it inline.
For pointer types, we have long supported:
char *foo = "bar";
int foo_len = 3;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &foo,
&foo_len) == FAILURE) return;
Which will leave foo as "bar" if NULL
is passed for the parameter.
Gustavo's diff for scalars adds '!' support (this was ignored
previously) by letting the NULL
get cast to the type (e.g.
false/0/0.0) and using a second zend_bool parameter to indicate if
NULL
was passed or not:
long num = 42;
zend_bool num_was_null;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l!", &num,
&num_was_null) == FAILURE) return;
Now if the func is called with NULL
as the argument, num will still be
overwritten to 0, but we'll get the flag indicating that NULL
got
passed in, and we're forced to reset it to the default value (assuming
that was our intent).
Now, I get that the implementation Gustavo went with does give more
information. We may want to handle passing NULL
differently from
explicitly passing (in this case) 42. The reason I don't like this,
is that it's really very inconsistent with established zpp semantics.
If the (anecdotally unusual) behavior of handling NULL
separately from
default value is really desired, the caller can always fallback on
accepting the zval and switching on type.
Thoughts?
-Sara
Gustavo's diff for scalars adds '!' support (this was ignored
previously) by letting theNULL
get cast to the type (e.g.
false/0/0.0) and using a second zend_bool parameter to indicate if
NULL
was passed or not:long num = 42;
zend_bool num_was_null;if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l!", &num,
&num_was_null) == FAILURE) return;Now if the func is called with
NULL
as the argument, num will still be
overwritten to 0, but we'll get the flag indicating thatNULL
got
passed in, and we're forced to reset it to the default value (assuming
that was our intent).[...]
Thoughts?
You raise a good point. From my part, feel free to modify it so the passed
long is not changed.
--
Gustavo Lopes
2013/2/2 Gustavo Lopes glopes@nebm.ist.utl.pt:
Gustavo's diff for scalars adds '!' support (this was ignored
previously) by letting theNULL
get cast to the type (e.g.
false/0/0.0) and using a second zend_bool parameter to indicate if
NULL
was passed or not:long num = 42;
zend_bool num_was_null;if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l!", &num,
&num_was_null) == FAILURE) return;Now if the func is called with
NULL
as the argument, num will still be
overwritten to 0, but we'll get the flag indicating thatNULL
got
passed in, and we're forced to reset it to the default value (assuming
that was our intent).[...]
Thoughts?You raise a good point. From my part, feel free to modify it so the passed
long is not changed.
Yeah, makes sense. +1
--
Regards,
Felipe Pena