On 2/13/2015 10:20 AM, Erik Aronesty wrote:
> It's a compile time issue, not a runtime issue, and the purpose is to
> set standards for compile-time pragmas that enable portability.
> Template hacks are unreadable, and unlikely to be used/useful.
[snip]
> If you have ever looked at "portable" C++ code, you would realize, very
> quickly, that this is an urgent, unmet need.
I disagree rather strongly. I don't believe this is the responsibility
of a compiler, but rather the responsibility of a build configuration
system. While the preprocessor is very fast, it's even faster to do this
*before* compilation, i.e. during the "configure" step of your build.
This way, incremental builds don't even need to perform this check. Not
only that, this allows for more complex configuration tests such as
ensuring that the semantics of a function match your expectations (e.g.
the XSI vs GNU versions of strerror_r). Perhaps in this example, the
differing return type (int vs char*) would be enough for your proposal
to detect the semantic difference, but this doesn't necessarily apply
universally.
There are still other problems, such as Windows' tendency to prefix C
runtime functions with "_", e.g. _isatty(). This is semantically the
same as isatty(), and an intelligent configuration system could abstract
out this difference for you (e.g. by automatically providing an isatty()
shim on Windows in some project-specific namespace), but I don't see how
a standard language feature could be expected to do this, especially
given that POSIX isatty() and Windows _isatty() are found in different
headers (unistd.h vs io.h).
Even the proposed (and already-implemented) __has_include directive is
somewhat suspect. While it can be nice for simple things, like picking
between std::experimental::any and boost::any, this is again a
configuration-time issue, not a compile-time issue. Worse, it doesn't
actually ensure that boost::any matches your expected interface: Boost
1.54 and below don't have boost::any::clear(), whereas the Library
Extensions proposal (and Boost 1.55+) do. Besides that, the boilerplate
to check this is a bit excessive, and I think it would make more sense
as autogenerated code. At that point, you could just unconditionally
#include the appropriate header (and alias the appropriate namespace) in
a generated-at-config-time header file.
I agree of course that better cross-platform configuration tools should
exist for C++, but I don't think they belong in the language itself. The
build configuration system* is a better place.
- Jim
* e.g. autotools, CMake, etc. Granted, build config systems are usually
painful to use, but that's an argument for a better build config system,
not for incorporating these features into the compiler.