Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:126242 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by qa.php.net (Postfix) with ESMTPS id 1BA8B1ADCB4 for ; Thu, 30 Jan 2025 15:51:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1738252107; bh=HRLGm+p1QALJPDyXaO4GGa9/5nFtC55Y4YHemNNtpfw=; h=Date:From:To:Subject:In-Reply-To:References:From; b=XHL6jQ0CPLhvdTtkzUsJ2jWnRIq92lZPSb/tY2rq4680De29BcIwAR5S+1GM4u7Ch wJXMQKVMqmuFwKICKkk0BIV2+R17vQYSZSvnP4bqQVPIAdcWa4CImLi470gqmzrnLg zcETmtt9b8q6mjrcQFIjLoIsOwItrpJrqL+uK0sIDvsVh5BcUDZCQeDocynQeVI+tz VGtQtiOOaG+sayz+T4RIX0rQDnHnI6PKxlQUaHsZH7eSic9BI8qctWvHSbTGg8/Ymo EvOmER0l9dWHT2aTORKhlvtFYyOUA6j/CkIHhMlPcFFLYRwwp5TFjMkKr1Ftublz7p QRj0eVeCTN73g== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id EA78C180071 for ; Thu, 30 Jan 2025 15:48:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=0.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from chrono.xqk7.com (chrono.xqk7.com [176.9.45.72]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Thu, 30 Jan 2025 15:48:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bastelstu.be; s=mail20171119; t=1738252269; bh=WYIRgoWyBx1CGwKaogrd536gMDOehSW3pQ9rvG4xV9k=; h=MIME-Version:Date:From:To:Subject:In-Reply-To:References: Message-ID:Content-Type:from:to:cc:subject:message-id; b=Y2nCHsSMlUT4Dn/A+GY5mZQ8PaPuxK4kRGhbzlCfp5lCcdOOsAWaZDrhTH0jwQVFw 7a5l2Hmdu6aS0TU9m0n/pte+5B/ImsgqQtlkhsOmwPlCqlk+LtgNs24FYFTCSGt3Ch nqNRuHTxcWrradUmUUlfLBa1RnA34AUK2Cva2sYO+Gnnl3blI5a8TBwpSqmnr7sUO3 eF5dJgF4xNEku+fba8whJ+asiFwlWXA+OZkrBDjbSXXnU3dQZGyOz+k3HlYF7w+is6 gcsY+TBknn1VSgPwwk8YrQGV0IH0j4QiwuQxpXz0JvkHiMPbf3u2pnCx7huddNMzLY P3wOPDdTi8iKQ== Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 Date: Thu, 30 Jan 2025 16:51:09 +0100 To: php internals Subject: Re: [PHP-DEV] RFC: Marking return values as important (#[\NoDiscard]) In-Reply-To: References: <3f170549-cfd6-441e-b892-cf51d726dbe8@bastelstu.be> <3b4d9be8-9255-44ab-95c5-ea3045212cf4@app.fastmail.com> Message-ID: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit From: tim@bastelstu.be (=?UTF-8?Q?Tim_D=C3=BCsterhus?=) Hi Am 2025-01-30 10:02, schrieb Rowan Tommins [IMSoP]: > I think it would be good to explore alternatives - for instance, I > think C# has a reserved _ variable to assign discarded results to, but > may be misremembering. A quick search confirms that C# supports the `_` variable. It's also supported with Rust. We are open to possible alternatives to the `(void)` cast, this was also something we discussed while drafting the RFC. However we opted for the `(void)` with out proposal for the following reasons: - `$_ = func();` is already working as a regular variable (see my reply to Rob regarding lifetimes), thus repurposing it as a “discard pile” would cause backwards compatibility issues. - `_ = func();` would introduce new syntax (just like `(void)`), but does not look and feel like PHP to us. - `(void)func();` has precedent in other languages (just like `_ =`) and looks and feels like PHP. In fact in earlier PHP versions there already was an `(unset)` cast to unconditionally turn an expression into `null`. We opted for `(void)` instead of bringing back `(unset)` for the following reasons: (1) Possible confusion about a deprecated + removed feature coming back (e.g. avoiding old blog articles). (2) More cleanly enforcing that `(void)` is a statement, rather than an expression. (3) The similarity with the `void` return type to indicate that “nothing” is returned. >> but my question is whether $_ = outer() and nop(outer()) will be >> guaranteed to not being optimized in a way which causes the warning to >> reappear. I don't know much about the optimizations being done but >> this could be an issue in the future, no? > > I second this concern: having code that you think has suppressed the > warning later be optimized and start warning could be very confusing, > and given the backwards compatibility issue, users will need something > other than "(void)" which is reliable. See my replies to Rob and Christian. > My other thought reading the proposal is that if this can be done > efficiently, can we use the same approach to warn when a "void" > function's return *is* used? Performing this check would be possible, but it would likely be less efficient. The current implementation of `#[\NoDiscard]` optimizes based on the assumption that the attribute is going to be comparatively rarely used (i.e. only when it actually matters, as per the “Recommended Usage” section of the RFC). The “Implementation Details” section already mentions this, but basically what's happening is that the checks for `#[\Deprecated]` and `#[\NoDiscard]` are happening at the same time (it's a bitflag check) and you are only paying the cost of the more detailed checks if the function is Deprecated or NoDiscard (or both). Then there's also the “OPcode specialization” to remove `#[\NoDiscard]` from the bitflag check when the return value is known to be used. And finally functions that are known to neither be `#[\Deprecated]` nor `#[\NoDiscard]` at compile time (this is mostly *fully-qualified* native functions) are going through an even faster OPcode that completely omits several safety checks. You can check this for yourself by passing a script through `php -d opcache.enable_cli=1 -d opcache.opt_debug_level=0x20000 script.php`. If you see `DO_ICALL` (native functions) or `DO_UCALL` (userland functions) then that's the optimized version omitting the checks. Here's an example: