Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:61530 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 36425 invoked from network); 19 Jul 2012 23:50:01 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 19 Jul 2012 23:50:01 -0000 Authentication-Results: pb1.pair.com smtp.mail=glopes@nebm.ist.utl.pt; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=glopes@nebm.ist.utl.pt; sender-id=unknown Received-SPF: error (pb1.pair.com: domain nebm.ist.utl.pt from 193.136.128.22 cause and error) X-PHP-List-Original-Sender: glopes@nebm.ist.utl.pt X-Host-Fingerprint: 193.136.128.22 smtp2.ist.utl.pt Linux 2.6 Received: from [193.136.128.22] ([193.136.128.22:43536] helo=smtp2.ist.utl.pt) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 80/20-18983-72D98005 for ; Thu, 19 Jul 2012 19:50:00 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp2.ist.utl.pt (Postfix) with ESMTP id ED3E470003D9; Fri, 20 Jul 2012 00:49:55 +0100 (WEST) X-Virus-Scanned: by amavisd-new-2.6.4 (20090625) (Debian) at ist.utl.pt Received: from smtp2.ist.utl.pt ([127.0.0.1]) by localhost (smtp2.ist.utl.pt [127.0.0.1]) (amavisd-new, port 10025) with LMTP id RSW8026y3YG3; Fri, 20 Jul 2012 00:49:55 +0100 (WEST) Received: from mail2.ist.utl.pt (mail.ist.utl.pt [IPv6:2001:690:2100:1::8]) by smtp2.ist.utl.pt (Postfix) with ESMTP id 3CD0470003D5; Fri, 20 Jul 2012 00:49:55 +0100 (WEST) Received: from damnation (unknown [IPv6:2001:470:94a2:4:75ff:ee1e:5e2e:eb71]) (Authenticated sender: ist155741) by mail2.ist.utl.pt (Postfix) with ESMTPSA id 1DEDA202250A; Fri, 20 Jul 2012 00:49:53 +0100 (WEST) Content-Type: text/plain; charset=utf-8; format=flowed; delsp=yes To: "Nikita Popov" , "Sara Golemon" Cc: "internals@lists.php.net" References: Date: Fri, 20 Jul 2012 01:49:50 +0200 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Organization: =?utf-8?Q?N=C3=BAcleo_de_Eng=2E_Biom=C3=A9di?= =?utf-8?Q?ca_do_I=2ES=2ET=2E?= Message-ID: In-Reply-To: User-Agent: Opera Mail/12.50 (Linux) Subject: Re: [PHP-DEV] zend_parse_parameters() improvements From: glopes@nebm.ist.utl.pt ("Gustavo Lopes") Em Fri, 20 Jul 2012 00:20:49 +0200, Sara Golemon escreveu: > Okay, well... the main pieces of feedback I'd give on it then is to not > change the behavior of the '!' modifier. That's bad BC. Rather, > introduce > a new modifier for checking if a parameter was passed. Secondly, make > these two separate patches as the new modifier is a separate feature from > the single-arg parameter parsing. > > FWIW, there are a few examples of this being handled by defining the > default value of the parameter to something non-sensical (such as a > length > of -1), then doing zpp with "|l!" would leave the default -1 alone when > NULL is passed, and you can treat as "not passed". Granted this is a bit > of a hack and won't work for all situations. Your approach is more > comprehensive, just saying that for many cases it's not strictly needed. > Stas managed to confuse you :) On an implementation level, this has nothing to do with default parameter values and unpassed parameters. As always, if you don't pass an argument, the pointers you give to zpp won't be touched. The behavior of ! is not changed insofar as it was not possible to use it with l, d or b (well actually it was ignored, so if anyone used l! their code will break as you now have to pass an extra argument, but it was wrong in the first place). Default parameters and unpassed parameters enter the scene because it's idiomatic to pass NULL to have the same effect as not passing that parameter. Consider this hypothetical internal function with signature: mb_substr(string $str, int $start [, int $length [, string $encoding ]]) Let's also imagine we want that the effect of not passing $length cannot be triggered by a specific value of $length (like -1) because the whole integer domain is used for something else. We have this check: if (ZEND_NUM_ARGS() < 3) { /* do special stuff */ } But now I cannot pass $encoding and not pass $length. I also can't wrap the function and pass-through arguments in an easy fashion. An idiomatic solution for this is to use NULL as a special value. In userspace: function mb_substr($str, $start, $length=NULL, $encoding=NULL) { if ($length === null) { /* do special stuff */ } However, the same is not possible with zpp because if we use 'l' and we send NULL, we'll get 0, which we cannot distinguish from an actual 0 being passed (or false, etc.). The first commit in the branch solves this problem. We could write: char *str, *encoding = NULL; int str_len, encoding_len; long start, length; zend_bool length_is_null = 0; zend_parse_parameters(..., "sl|l!s!, &str, &str_len, &start, &length, &length_is_null, &encoding) Then we have length_is_null == 0 <=> $length was not passed or NULL was its value (just like the userland check above). -- Gustavo Lopes