# Non-pointer params, zend_parse_parameters, and the "!" modifier

- Thread: https://externals.io/message/65560
- Original archive: https://news-web.php.net/php.internals/65560
- Started by Sara Golemon on 2013-02-02T13:36:00+00:00
- Messages: 3
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #65560 — Sara Golemon — 2013-02-02T13:36:00+00:00

URL: https://externals.io/message/65560#65560

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

---

## #65561 — Gustavo Lopes — 2013-02-02T14:06:22+00:00

URL: https://externals.io/message/65560#65561 · In reply to: #65560

> 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).
>
> [...]
>Thoughts?

You raise a good point. From my part, feel free to modify it so the passed  
long is not changed.

-- 
Gustavo Lopes

---

## #65562 — Felipe Pena — 2013-02-02T14:11:19+00:00

URL: https://externals.io/message/65560#65562 · In reply to: #65561

2013/2/2 Gustavo Lopes <glopes@nebm.ist.utl.pt>:
> 
>
> > […]
>
>
> 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
