Bug 78905

Summary: Add a macro to determine that the <regex> library is implemented
Product: gcc Reporter: Matt Clarkson <mattyclarkson>
Component: libstdc++Assignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: enhancement CC: webrown.cpp
Priority: P3    
Version: unknown   
Target Milestone: 7.0   
URL: http://stackoverflow.com/a/41186162/192993
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2016-12-23 00:00:00

Description Matt Clarkson 2016-12-22 17:39:25 UTC
libstdc++ 4.7 and 4.8 shipped with a incomplete <regex> implementation. Detecting this is a bit of a pain. I did my best to attempt a detection snippet with:

#include <regex>
#if __cplusplus >= 201103L &&                             \
    (!defined(__GLIBCXX__) || (__cplusplus >= 201402L) || \
        (defined(_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT) || \
         defined(_GLIBCXX_REGEX_STATE_LIMIT)))
#define HAVE_WORKING_REGEX 1
#else
#define HAVE_WORKING_REGEX 0
#endif

This uses internal macros that are not guaranteed to exist. Would it be possible to include a _GLIBCXX_REGEX_IMPLEMENTED (or similar) that would be supported in future versions of the library so that the snippet can be updated so that it doesn't break for future versions of the library?

I wrote a more lengthy description of the solution on stackoverflow:

http://stackoverflow.com/a/41186162/192993
Comment 1 Andrew Pinski 2016-12-22 17:42:41 UTC
Why don't you use:
__GNUC__ >=5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)

instead for checking GCC version?
Comment 2 Matt Clarkson 2016-12-22 17:44:20 UTC
Because wehen I compile with clang against the libstdc++ the problem will still occur and __GNUC__ will not be defined. This happens on any distro where GCC is the default but ships clang as an alternative compiler.
Comment 3 Andrew Pinski 2016-12-22 17:49:13 UTC
(In reply to Matt Clarkson from comment #2)
> Because wehen I compile with clang against the libstdc++ the problem will
> still occur and __GNUC__ will not be defined. This happens on any distro
> where GCC is the default but ships clang as an alternative compiler.

Not something which GCC supports directly.  You need to ask clang folks about that :).

Anyways 4.9.x is no longer maintained; there will be no new releases after the current release of 4.9.4 (which happened two years after the first release of 4.9.0).
Comment 4 Matt Clarkson 2016-12-22 18:11:09 UTC
That's OK. I'm not particularly looking for the macro to be backported to 4.9. Just as we move forward the new macro is available. If not it's not the end of the world I can always maintain the snippet internally.
Comment 5 Jonathan Wakely 2016-12-23 02:07:23 UTC
I asked for this to be created.
Comment 6 Jonathan Wakely 2017-01-19 16:41:18 UTC
Author: redi
Date: Thu Jan 19 16:40:46 2017
New Revision: 244642

URL: https://gcc.gnu.org/viewcvs?rev=244642&root=gcc&view=rev
Log:
PR78905 define _GLIBCXX_RELEASE macro

	PR libstdc++/78905
	* doc/xml/manual/abi.xml (abi.versioning.history): Add markup to
	macro names, filenames, and literal values. Document _GLIBCXX_RELEASE.
	Document that the deprecated _GLIBCXX_VERSION macro was removed for
	the 4.0.0 release.
	* doc/html/*: Regenerate.
	* include/Makefile.am (_GLIBCXX_RELEASE): Set value.
	* include/Makefile.in: Regenerate.
	* include/bits/c++config (_GLIBCXX_RELEASE): Add #define.
	* testsuite/ext/profile/mutex_extensions_neg.cc: Use lineno of 0 in
	dg-error.

Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/doc/html/manual/abi.html
    trunk/libstdc++-v3/doc/xml/manual/abi.xml
    trunk/libstdc++-v3/include/Makefile.am
    trunk/libstdc++-v3/include/Makefile.in
    trunk/libstdc++-v3/include/bits/c++config
    trunk/libstdc++-v3/testsuite/ext/profile/mutex_extensions_neg.cc
Comment 7 Jonathan Wakely 2017-01-19 17:20:21 UTC
GCC 7 now defines _GLIBCXX_RELEASE (with the same value as __GNUC__ has, i.e. the GCC major version, as an integer constant, but defined by the library headers not the compiler).

If that macro is present you have a version of libstdc++ that provides a working <regex>. To be really sure you could check it's defined to a value >= 5, in order to handle (hypothetical) unofficial 4.7 or 4.8 builds that have the patch backported.
Comment 8 Jonathan Wakely 2017-01-19 17:22:04 UTC
(In reply to Matt Clarkson from comment #2)
> Because wehen I compile with clang against the libstdc++ the problem will
> still occur and __GNUC__ will not be defined.

N.B. Clang does define __GNUC__ but it always defines it to 4 (and defines __GNUC_MINOR__ to 1 and __GNUC_PATCHLEVEL__ to 2, because it identifies as GCC 4.1.2, the last release Apple shipped for their OS).
Comment 9 Matt Clarkson 2017-01-19 20:25:53 UTC
(In reply to Jonathan Wakely from comment #7)
> GCC 7 now defines _GLIBCXX_RELEASE (with the same value as __GNUC__ has,
> i.e. the GCC major version, as an integer constant, but defined by the
> library headers not the compiler).
> 
> If that macro is present you have a version of libstdc++ that provides a
> working <regex>. To be really sure you could check it's defined to a value
> >= 5, in order to handle (hypothetical) unofficial 4.7 or 4.8 builds that
> have the patch backported.

Sweet! Will update the snippet on Stack Overflow. Thank you for this, you the man ;)
Comment 10 Eric Gallager 2017-01-22 18:39:13 UTC
(In reply to Jonathan Wakely from comment #8)
> (In reply to Matt Clarkson from comment #2)
> > Because wehen I compile with clang against the libstdc++ the problem will
> > still occur and __GNUC__ will not be defined.
> 
> N.B. Clang does define __GNUC__ but it always defines it to 4 (and defines
> __GNUC_MINOR__ to 1 and __GNUC_PATCHLEVEL__ to 2, because it identifies as
> GCC 4.1.2, the last release Apple shipped for their OS).

__GNUC_MINOR__ and __GNUC_PATCHLEVEL__ values are swapped with each other there; last release Apple shipped for their OS was 4.2.1, not 4.1.2
Comment 11 Jonathan Wakely 2017-07-07 13:54:34 UTC
*** Bug 81353 has been marked as a duplicate of this bug. ***