php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #76826 error: use of undeclared identifier 'finite'
Submitted: 2018-08-31 04:11 UTC Modified: 2018-11-18 22:41 UTC
Votes:2
Avg. Score:3.5 ± 0.5
Reproduced:2 of 2 (100.0%)
Same Version:2 (100.0%)
Same OS:2 (100.0%)
From: php-bugs-2018 at ryandesign dot com Assigned:
Status: No Feedback Package: Compile Failure
PHP Version: 7.2.9 OS: Mac OS X 10.7.5
Private report: No CVE-ID: None
 [2018-08-31 04:11 UTC] php-bugs-2018 at ryandesign dot com
Description:
------------
Building the bundled intl extension (I happen to build it separately from php, using phpize) fails on Mac OS X 10.7.5 (with clang 425.0.28 as provided by Xcode 4.6.3), in several PHP versions (7.2.9, 7.1.21). It worked in previous PHP versions. Here's the error message from PHP 7.2.9:


In file included from ext/intl/intl_convertcpp.cpp:24:
In file included from /opt/local/include/php72/php/main/php.h:35:
In file included from /opt/local/include/php72/php/Zend/zend.h:328:
/opt/local/include/php72/php/Zend/zend_operators.h:114:18: error: use of undeclared identifier 'finite'
        if (UNEXPECTED(!zend_finite(d)) || UNEXPECTED(zend_isnan(d))) {
                        ^
/opt/local/include/php72/php/main/../main/php_config.h:2619:24: note: expanded from macro 'zend_finite'
#define zend_finite(a) finite(a)
                       ^
/opt/local/include/php72/php/Zend/zend_portability.h:312:52: note: expanded from macro 'UNEXPECTED'
# define UNEXPECTED(condition) __builtin_expect(!!(condition), 0)
                                                   ^


Perhaps it was caused by this commit: https://github.com/php/php-src/commit/ad790bea2e4a8a25c79ceab964601f3785cd2bf1


Patches

bug76826.poc.0.patch (last revision 2018-10-05 07:09 UTC by ab@php.net)

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-09-03 12:53 UTC] ab@php.net
-Status: Open +Status: Feedback
 [2018-09-03 12:53 UTC] ab@php.net
Thanks for the report. Perhaps you need to use phpize from the same (or at least) PHP version. Older PHP versions will have different php_config.h. Otherwise, ext/intl can also be built shared.

Btw, what does __cplusplus macro contain?

Thanks.
 [2018-09-03 13:08 UTC] php-bugs-2018 at ryandesign dot com
-Status: Feedback +Status: Open
 [2018-09-03 13:08 UTC] php-bugs-2018 at ryandesign dot com
I do use phpize from the same version of PHP. I know that intl can be built as a separate extension using phpize; we do so in MacPorts. This bug report is that on this specific version of Mac OS X with its version of Xcode, and this version of PHP, it fails to compile. It's not a problem with older versions of PHP on this version of Mac OS X and Xcode, and it's not a problem with this version of PHP on other versions of Mac OS X and Xcode.

Both on Mac OS X 10.7 where the build fails, and on 10.8 and later up to at least 10.13 where the build succeeds, __cplusplus is 199711L. On Mac OS X 10.6 where the build also succeeds, the Apple gcc 4.2.1 compiler is used, and its __cplusplus value is 1.
 [2018-09-17 09:51 UTC] elis at hirwing dot se
In Nix we have the same issue when building our packages on darwin.

It's present in 7.2.9, 7.2.10 as well as 7.1.21. It's not present in 7.0.32 or 5.6.38.

Here's a full build log of 7.2.10 on Darwin: https://logs.nix.ci/?key=nixos/nixpkgs.46694&attempt_id=f33785ed-b114-4eee-82b6-83fe93439e25

For the moment we have disabled the intl module on Darwin just to get the new versions into our unstables. But since we changed the feature set available it also means that we're unable to backport bug fix releases to our users of our stable channels on both NixOS, other Linux and Darwin.
 [2018-10-04 20:27 UTC] ab@php.net
-Status: Open +Status: Feedback
 [2018-10-04 20:27 UTC] ab@php.net
@elis the build log seems to available anymore. Perhaps a gist could work? Also the OS and compiler version were interesting to know.

@php-bugs-2018 Otherwise I was doing some research and stumbled upon the fact, that OS X 10.7 is EOL already for about 4 years. It seems that even 10.9 already EOL. The issue seems quite weird because the condition https://github.com/php/php-src/blob/master/configure.ac#L85 checks already whether it's lower than C++11. You could try to remove __cplusplus check in configure.ac and Zend/configure.ac and see whether it changes something. If it doesn't, that it is probably missing the other part of the condition.

Thanks.
 [2018-10-05 02:35 UTC] php-bugs-2018 at ryandesign dot com
-Status: Feedback +Status: Open
 [2018-10-05 02:35 UTC] php-bugs-2018 at ryandesign dot com
Yes, we know Mac OS X 10.7 is old. But maybe there's somebody out there trying to learn PHP, and the only computer they have available is an old hand-me-down Mac that cannot be upgraded past 10.7.

Here are some fresh build logs for you, on Mac OS X 10.7.5, Xcode 4.6.3, Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn).

php 7.1.22: https://build.macports.org/builders/ports-10.7_x86_64_legacy-builder/builds/78701/steps/install-port/logs/stdio

php 7.2.10: https://build.macports.org/builders/ports-10.7_x86_64_legacy-builder/builds/78702/steps/install-port/logs/stdio

Can't provide a build log of php 7.3.x because of bug #76825.
 [2018-10-05 07:09 UTC] ab@php.net
The following patch has been added/updated:

Patch Name: bug76826.poc.0.patch
Revision:   1538723399
URL:        https://bugs.php.net/patch-display.php?bug=76826&patch=bug76826.poc.0.patch&revision=1538723399
 [2018-10-05 07:13 UTC] ab@php.net
-Status: Open +Status: Feedback
 [2018-10-05 07:13 UTC] ab@php.net
Thanks for the build new logs. Is that with the vanilla package? Were you able to play with the condition as i've suggested? Perhaps you could try the patch i've just attached. I'd be really reluctant to do fixes for EOL versions, but at least we could figure out what goes wrong there. Probably only you can do that, as the chances to find someone with this OSX version are probably marginal.

Thanks.
 [2018-10-11 21:15 UTC] elis at hirwing dot se
@ab I've completely missed the answers here. I have tried to build 7.2.11 and 7.1.23 which have failed the same way.

Too bad it's the same log viewer as before: https://logs.nix.ci/?key=nixos/nixpkgs.48228&attempt_id=94e95849-958b-4b83-8952-90bc4cf3021f -- but it's the only way I have to get the log out from the darwin builds since I don't have any darwin machines myself.

I've also tried to apply your patch on 7.2.11 and 7.1.23 for darwin, but it didn't apply at all: https://logs.nix.ci/?key=nixos/nixpkgs.48228&attempt_id=7d415ce6-e908-439e-bbf4-5fe6797871c8
 [2018-10-11 22:26 UTC] ab@php.net
@elis yep, that's the same bug. Thanks for re-posting the log. I've no Mac as well, so only able to guess the conditions. With the patch - you need to ensure the -p option has the correct level number, depending on the CWD when the patch gets applied. Alternatively you can edit the paths in the patch, so they suffice for the build constellation.

Thanks.
 [2018-10-13 07:28 UTC] elis at hirwing dot se
@ab - I think the reason for the patch not applying was because the lines it tried to remove wasn't there in that version of the source that it tried to patch. It also seems to differ between 7.1.X and 7.2.X what they look like.

Make sure to take a copy of the log if you have use for it since it will go away. Nothing I can do about that :/

Also, could you lend me some pointer to how to subscribe to this issue. I've tried several times to fill email, solve math-problem and press subscribe but haven't got a single message.
 [2018-10-16 01:07 UTC] php-bugs-2018 at ryandesign dot com
-Status: Feedback +Status: Open
 [2018-10-16 01:07 UTC] php-bugs-2018 at ryandesign dot com
I am not a C++ programmer but from what I've been able to research, "finite" is an old deprecated method of determining if a number is finite, and "isfinite" is its replacement, available as of C99.

Given that, the PHP code used to make sense: It used to use "isfinite" if it was available, and otherwise it would use "finite" if that was available. The change in ad790bea2e4a8a25c79ceab964601f3785cd2bf1 seems wrong to me, because now, if compiling in C++11 mode or newer, the newer "isfinite" method isn't used, and the deprecated "finite" is used instead. Why would we want to use a deprecated function when a newer replacement function is available, especially if we're compiling in a newer language mode?

The reason for the compile failure I reported appears to be that the intl extension uses icu, and used `icu-config --cxxflags` to get the flags it should use. We're using icu 58.2 in MacPorts, and it returns "--std=c++0x". (Yes, there is a typo: it should be one dash instead of two, but the compiler still recognizes the flag despite that.) The intl extension was changed in 4acc8500acd134dfab1a2ddb83aeb39fa1033abe on 9/28/2018 to always use C++11 mode regardless what ICU says. So we're in C++11 mode and __cplusplus is 201103L which is why PHP is now trying (misguidedly, in my opinion) to use "finite" here. I've also seen the same problem when building the third-party swoole extension, which also uses C++11.

So why doesn't "finite" exist, even though HAVE_FINITE is 1? On Mac OS X 10.7, /usr/include/math.h is just a wrapper that includes /usr/include/architecture/i386/math.h, and in that file, the definition of "finite" and other deprecated functions is inside a block which checks:

#if !defined( __STRICT_ANSI__) && !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))

And it turns out that __STRICT_ANSI__ is defined (due, I believe, to requesting conformance to an ISO C/C++ standard, in this case c++0x), therefore these legacy functions don't get defined. I can get the build to succeed on 10.7 by undefining __STRICT_ANSI__ (e.g. by adding "-U__STRICT_ANSI__" to CXXFLAGS), though I don't know what other implications that might have elsewhere in the system headers so I don't think this is the solution we want to use.

In OS X 10.8, Apple moved the header to /usr/include/math.h and rewrote it so that it only checks:

#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL

__DARWIN_C_LEVEL is defined to be __DARWIN_C_FULL so on 10.8 and later old "finite" is still available in strict ANSI mode.

As for why it also built successfully on 10.6, that's because on that system `icu-config --cxxflags` returns nothing, because the old g++ 4.2.1 compiler on that system doesn't have any C++11 support. Therefore we're not in strict ANSI mode, therefore the deprecated functions are still defined.

I have tried reverting ad790bea2e4a8a25c79ceab964601f3785cd2bf1 and it builds successfully on 10.7, and still builds fine on 10.13, despite the fact that the commit message for ad790bea2e4a8a25c79ceab964601f3785cd2bf1 says that "isfinite" was supposed to have moved into the std namespace as of C++11. Further research tells me that "isfinite" and friends are only in the std namespace if you #include <cmath>. PHP doesn't do that; instead, it includes the older <math.h>, in which case those functions are not in the std namespace. I believe this confirms my suspicion that ad790bea2e4a8a25c79ceab964601f3785cd2bf1 doesn't do anything useful and should be reverted.
 [2018-10-18 23:11 UTC] ab@php.net
-Status: Open +Status: Feedback
 [2018-10-18 23:11 UTC] ab@php.net
Thanks for the detailed analysis. The finite family is  with this regardobsolete because C99 defines isfinite, the man page says, but all the current PHP versions don't use strict C99. In how far isfinite is better or finite is worse, is another question.

This issue seems to show up in quite different constellations, it is hard to find a middle ground. There was same issue reported in bug #74904 on Solaris, which was fixed by the existing patch (though other C++ issues arise). I  with this regardwas able to reproduce this issue with older versions of gcc on Linux, too. Namely from gcc 4.9.x to gcc 5.x.x. 

Now, on the Apple side, not sure whether C99 is default, but isfinite should definitely not be there when C++11 or up is compiled. With C++ it has to be std::isfinite from cmath. On some gcc versions however, including cmath brings another can of bugs, so the best way looks like to avoid it for now.

The facts you depict confirm as well, that this math.h vs. cmath/C++ topics in regard to differnet platforms and compiler versions are handled in very different ways and a diligence is due to keep and improve the compatibility. Were you able also to check the attached patch, which makes an exception for the Apple platform? If Apple allows isfinite even if C++11 is compiled, then that might be the way to solve it for that platform. 

We might have it easier, when PHP has switched to C99. That however is to be checked and anyway won't affect already released branches.

Thanks.
 [2018-11-18 22:41 UTC] cmb@php.net
-Status: Feedback +Status: No Feedback
 [2018-11-18 22:41 UTC] cmb@php.net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 11:01:29 2024 UTC