C++ Logo


Advanced search

Re: [SG10] Comments from Alisdair

From: Nelson, Clark <clark.nelson_at_[hidden]>
Date: Fri, 30 May 2014 17:07:50 +0000
> > [3] Fortunately Clang has ways to test specifically for the
> presence of
> > specific features. But unfortunately, the function-call-like
> syntax used
> > for such tests won't work with a standard preprocessor, so this
> fine new
> > feature winds up adding its own flavor of complexity to the mix.
> Thanks for pointing that out. Unfortunately I do not know what
> does or does
> not make a 'standard preprocessor', so I don't understand. What is
> the
> difference, in that sense, between __has_include and
> __has_feature?

A standard preprocessor is a preprocessor that does (only) what the standard
actually requires, which does not include __has_feature.

The capability of __has_include is implicit in what the preprocessor has to
do anyway, in interacting with the compilation environment: it has to be
able to look for a file by name, and tell when it can't be found, so it can
report a diagnostic against the attempt. What __has_include does is just
give the C programmer the option of doing something other than crapping out
in those circumstances. Once it's possible to recognize a __has_include
construct, its implementation is trivial.

But __has_feature would require a brand-new kind of integration between the
preprocessor and the compiler proper. Remember that the original
preprocessor finished running before the compiler proper was even invoked.
The standards committees have been careful to keep this design option open
to implementers. (Or at least they were until raw strings came along -- but
I digress.)

In a design like that, a compiler would have to make available to the
preprocessor, presumably before invoking it, a table of all the features it
supports. That was just too much novelty for SG10, which is by its nature a
group that cares very much about backward compatibility.

Of course the same is true about __has_cpp_attribute. But there are two
practical differences between __has_[cpp_]attribute and __has_feature. One
is that, for an attribute, the "key" to refer to a specific item is
basically given; for a general feature, the key needs to be invented
separately. The other is the common expectation that an unrecognized
attribute will be ignored, and not an error.

> > To put it more bluntly, SG10's purpose is to make it possible
> for a
> > program to detect what new features are present in an
> implementation. If
> > we had made a recommendation that depended entirely on the
> existence of
> > yet another new feature, we would have built a castle in the
> air.
> I don't understand this either I'm afraid :(.
> Are you suggesting that something similar to the __has_include
> example in
> the document can not work or is fundamentally undesirable?
> #ifdef __has_feature
> # if __has_feature(cpp_variadic_templates)
> # endif
> #endif

Not at all. But consider the equivalent code using SG10's recommendations:

#if __cpp_variadic_templates

Obviously, it's simpler to write, since you don't need to check to see if
__has_feature is available before using it. And it doesn't require a
specially modified preprocessor; it uses only standard preprocessor

Unquestionably, __has_feature had a significant influence on SG10 and our
recommendations. The main influences had to do with the discipline of
thinking about the impact of adding features, and about granularity (what "a
feature" really is).

The fact that we went with a different syntax has to do with low-level,
nitty-gritty details. It was absolutely *not* due to a lack of appreciation
or gratitude, nor even from a desire to put our own stamp on things.


Received on 2014-05-30 19:08:30