Preprocessor operators for #error and #warning

Hello,

I'd really like to generate #error and #warning tokens from macros. How
interested would the clang team be in accepting an extension that made
_Error() and _Warning() operators available, similar to C99's _Pragma()
operator?

One preferable difference from _Pragma would be for _Error() and
_Warning() to accept implicit string concatenation. So, for example,
`#define fail(msg) _Error("failed: " msg)` should work—even though it
doesn't work with _Pragma.

Ideally, I'd be able to use printf()-style formatting, since that's what
my macro gets converted to for debug builds. (I want them to convert to
compile-time errors in release builds, to prevent shipping code that
contains that code branch.) But I can understand not wanting to do
string formatting within the compiler.

--Kyle Sluder

For _Error, you can use C11's _Static_assert():

#define fail(msg) _Static_assert(0, msg)

There's no standard equivalent for #warning, unfortunately.

David

That workaround is sufficient for my use case, but the output is noisy and as you note it doesn’t work for those who treat warning differently from errors.

So, can anyone opine on whether such a patch would be accepted?

--Kyle Sluder

I don't think we want _Warning and _Error. You can use #pragma message to
emit a warning (as _Pragma("message \"...\"") within your macro). I'd much
prefer to add support for something like '#pragma clang error "blah"'
rather than adding something like _Error(...), if _Static_assert is somehow
insufficient, but I'd like to understand what's wrong with _Static_assert
first.

Such a macro definition is sadly impossible because the C99 spec is too strict: _Pragma only accepts a single string literal. No implicit concatenation of string literals is allowed.

If the clang folks are fine with relaxing that, then _Pragma becomes sufficient for my purposes. But I presume it was so strictly defined in the spec for some reason.

Well, for starters, it can’t be used to produce a warning. That alone makes it worth contemplating alternatives, in my view.

But even for the error-producing use case, the error output contains a lot of noise about failing nonsensical assertion conditions. The best thing about #error and #warning is that I get to control the output, and that lets me match clang’s much-lauded user-friendliness in my own error messages.

–Kyle Sluder

>
> For _Error, you can use C11's _Static_assert():
>
> #define fail(msg) _Static_assert(0, msg)
>
> There's no standard equivalent for #warning, unfortunately.

That workaround is sufficient for my use case, but the output is noisy
and as you note it doesn’t work for those who treat warning differently
from errors.

So, can anyone opine on whether such a patch would be accepted?

I don't think we want _Warning and _Error. You can use #pragma message to
emit a warning (as _Pragma("message \"...\"") within your macro).

Such a macro definition is sadly impossible because the C99 spec is too
strict: _Pragma only accepts a single string literal. No implicit
concatenation of string literals is allowed.

If the clang folks are fine with relaxing that, then _Pragma becomes
sufficient for my purposes. But I presume it was so strictly defined in the
spec for some reason.

You don't need string literal concatenation to make this work. Here's a
hint, from C11 6.10.9/2:

#define PRAGMA(x) _Pragma(#x)

I'd much prefer to add support for something like '#pragma clang error

"blah"' rather than adding something like _Error(...), if _Static_assert is
somehow insufficient, but I'd like to understand what's wrong with
_Static_assert first.

Well, for starters, it can’t be used to produce a warning. That alone
makes it worth contemplating alternatives, in my view.

I explained how to get a warning above =) I was only talking about the
error case here.

But even for the error-producing use case, the error output contains a lot

of noise about failing nonsensical assertion conditions. The best thing
about #error and #warning is that I get to control the output, and that
lets me match clang’s much-lauded user-friendliness in my own error
messages.

OK, if you don't like the 'static assertion failed' text added by
_Static_assert, then use this:

#define pragma(...) _Pragma(#__VA_ARGS__)
#define warning(msg) pragma(GCC warning(msg))
#define error(msg) pragma(GCC error(msg))

Oh, I was unaware of `#pragma GCC warning` and `#pragma GCC error`.

Thanks very much,
--Kyle Sluder