[FYI] C++ compilers vs. __cplusplus (was Re: SV: Re: make failed for editors/libreoffice)

Jung-uk Kim jkim at FreeBSD.org
Wed Jul 18 23:34:11 UTC 2012


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

While I was tackling LibreOffice build issues, I found something
interesting about __cplusplus.  Basically, different C++ compilers may
have different __cplusplus definitions and it may cause some
strangeness.  Clang, for example, used to set it to 1 but now it is
set to C++ standard value since this commit:

http://llvm.org/viewvc/llvm-project?view=rev&revision=156113

This is what I got from head:

GCC:
% cpp --version
cpp (GCC) 4.2.1 20070831 patched [FreeBSD]
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.

% cpp -x c++ -dM /dev/null | grep __cplusplus
#define __cplusplus 1
% cpp -x c++ -std=gnu++98 -dM /dev/null | grep __cplusplus
#define __cplusplus 1

Clang 3.1:
% clang-cpp --version
FreeBSD clang version 3.1 (branches/release_31 156863) 20120523
Target: x86_64-unknown-freebsd10.0
Thread model: posix
% clang-cpp -x c++ -std=c++98 -dM /dev/null | grep __cplusplus
#define __cplusplus 199711L
% clang-cpp -x c++ -std=c++0x -dM /dev/null | grep __cplusplus
#define __cplusplus 201103L
% clang-cpp -x c++ -std=gnu++98 -dM /dev/null | grep __cplusplus
#define __cplusplus 1
% clang-cpp -x c++ -std=gnu++0x -dM /dev/null | grep __cplusplus
#define __cplusplus 1

Clang 3.2 snapshot (ports/lang/clang-devel):
% /usr/local/bin/clang++ --version
clang version 3.2 (trunk)
Target: amd64-portbld-freebsd10.0
Thread model: posix
% /usr/local/bin/clang++ -E -x c++ -std=c++98 -dM /dev/null | grep
__cplusplus
#define __cplusplus 199711L
% /usr/local/bin/clang++ -E -x c++ -std=c++0x -dM /dev/null | grep
__cplusplus
#define __cplusplus 201103L
% /usr/local/bin/clang++ -E -x c++ -std=gnu++98 -dM /dev/null | grep
__cplusplus
#define __cplusplus 199711L
% /usr/local/bin/clang++ -E -x c++ -std=gnu++0x -dM /dev/null | grep
__cplusplus
#define __cplusplus 201103L

and so on and so forth...

This causes very subtle issues depending on compiler versions and
FreeBSD versions.  For example, NULL may be defined differently
because stable/9 and head have this:

#if __cplusplus >= 201103L
#define NULL    nullptr
#elif defined(__GNUG__) && defined(__GNUC__) && __GNUC__ >= 4
#define NULL    __null
#else
#if defined(__LP64__)
#define NULL    (0L)
#else
#define NULL    0
#endif  /* __LP64__ */
#endif  /* __GNUG__ */

Before that, we had this:

#if defined(__GNUG__) && defined(__GNUC__) && __GNUC__ >= 4
#define	NULL	__null
#else
#if defined(__LP64__)
#define	NULL	(0L)
#else
#define	NULL	0
#endif	/* __LP64__ */
#endif	/* __GNUG__ */

What a mess...

Jung-uk Kim
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (FreeBSD)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAlAHR/IACgkQmlay1b9qnVNd0QCfX1NPpOfc+haRebvmBb1+nMSY
KAUAn3A6vKEaV0FQy82gysnV79UdejMf
=7G3Z
-----END PGP SIGNATURE-----


More information about the freebsd-ports mailing list