On 2/13/19 2:46 PM, Martin Sebor wrote:
The attached patch adds documentation for the __has_attribute (and
__has_cpp_attribute) and __has_include operators added in r215752.
Thanks!
I was a little unsure where to add this, whether the preprocessor
manual or the GCC manual, or both. It seems that it belongs in
the preprocessor manual but since more users read the GCC manual,
it's likely to be overlooked there.
I think the preprocessor manual is the right place. A while back I
brought up the idea of consolidating the preprocessor docs into the GCC
manual but the consensus seemed to be for retaining a separate
preprocessor manual.
My comments on this patch are mostly trivial markup things.
@@ -3422,6 +3425,99 @@ condition succeeds after the original @samp{#if} a
@samp{#else} is allowed after any number of @samp{#elif} directives, but
@samp{#elif} may not follow @samp{#else}.
+@node __has_attribute
+@subsection __has_attribute
Please use @code markup in the @subsection.
+@cindex @code{__has_attribute}
+
+The special operator @code{__has_attribute (operand)} may be used in
@code{__has_attribute (@var{operand})}
+@samp{#if} and @samp{#elif} expressions to test whether the attribute
+referenced by its argument is recognized by GCC. Using the operator
+in other contexts is not valid. In C code, @var{operand} must be
+a valid identifier. In C++ code, @var{operand} may be optionally
+introduced by the @code{attribute-scope::} prefix.
I think "attribute-scope" is not a literal part of the prefix, so
@code{@var{attribute-scope}::}
+The @code{attribute-scope} prefix identifies the ``namespace'' within
And @var markup here, too.
+which the attribute is recognized. The scope of GCC attributes is
+@samp{gnu} or @samp{__gnu__}. The operator by itself, without any
The @code{__has_attribute} operator by itself....
+@var{operand} or parentheses, acts as a predefined macro so that support
+for it can be tested in portable code. Thus, the recommended use of
+the operator is as follows:
+
+@smallexample
+#if defined __has_attribute
+# if __has_attribute (nonnull)
+# define ATTR_NONNULL __attribute__ ((nonnull))
+# endif
+#endif
+@end smallexample
+
+The first @samp{#if} test succeeds only when the operator is supported
+by the version of GCC (or another compiler) being used. Only when that
+test succeeds is it valid to use @code{__has_attribute} as a preprocessor
+operator. As a result, combining the two tests into a single expression as
+shown below would only be valid with a compiler that supports the operator
+but not with others that don't.
+
+@smallexample
+#if defined __has_attribute && __has_attribute (nonnull) /* not portable */
+@dots{}
+#endif
+@end smallexample
+
+@node __has_cpp_attribute
+@subsection __has_cpp_attribute
@code markup in the @subsection title, again.
+@cindex @code{__has_cpp_attribute}
+
+The special operator @code{__has_cpp_attribute (operand)} may be used
@var{operand} markup again.
+in @samp{#if} and @samp{#elif} expressions in C++ code to test whether
+the attribute referenced by its argument is recognized by GCC.
+@code{__has_cpp_attribute (operand)} is equivalent to
+@code{__has_attribute (operand)} except that when @code{operand}
The 3 instances above too.
+designates a supported standard attribute it evaluates to an integer
+constant of the form @code{YYYYMM} indicating the year and month when
+the attribute was first introduced into the C++ standard. For additional
+information including the dates of the introduction of current standard
+attributes, see
@w{@uref{https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations/,
+SD-6: SG10 Feature Test Recommendations}}.
+
+@node __has_include
+@subsection __has_include
@code markup in title again
+@cindex @code{__has_include}
+ > +The special operator @code{__has_include (operand)} may be used in
@samp{#if}
@var{operand}
+and @samp{#elif} expressions to test whether the header referenced by its
+@var{operand} can be included using the @samp{#include} directive. Using
+the operator in other contexts is not valid. The @var{operand} takes
+the same form as the file in the @samp{#include} directive (@xref{Include
+Syntax}) and evaluates to a nonzero value if the header can be included and
+to zero otherwise. Note that that the ability to include a header doesn't
+imply that the header doesn't contain invalid constructs or @samp{#error}
+directives that would cause the preprocessor to fail.
+
+The @code{__has_include} operator by itself, without any @var{operand} or
+parentheses, acts as a predefined macro so that support for it can be tested
+in portable code. Thus, the recommended use of the operator is as follows:
+
+@smallexample
+#if defined __has_include
+# if __has_include (<stdatomic.h>)
+# include <stdatomic.h>
+# endif
+#endif
+@end smallexample
+
+The first @samp{#if} test succeeds only when the operator is supported
+by the version of GCC (or another compiler) being used. Only when that
+test succeeds is it valid to use @code{__has_include} as a preprocessor
+operator. As a result, combining the two tests into a single expression
+as shown below would only be valid with a compiler that supports the operator
+but not with others that don't.
+
+@smallexample
+#if defined __has_include && __has_include ("header.h") /* not portable */
+@dots{}
+#endif
+@end smallexample
+
@node Deleted Code
@section Deleted Code
@cindex commenting out code
OK with those changes.
-Sandra