static_warning

1,004 views
Skip to first unread message

gmis...@gmail.com

unread,
Aug 27, 2014, 5:46:03 PM8/27/14
to std-pr...@isocpp.org
There seems to be know standard way of issuing a warning with the expectation that compilation will continue.

We have #warning but it isn't standard.
We have static_assert but it always stops compilation.

What about making #warning standard, or introducing static_warning that works like static_assert but doesn't stop compilation.
Or an additional default parameter to static_assert that determines if compilation should continue or not - the default being that compilation stops..

There is a reasonable amount of code that uses #warning on the theory that it is standard because most compilers do support it, but msvc is one that doesn't and the work around isn't pretty and often leads to more warnings on other platforms or clouds the intended warning.

Use case might  be something  like:
#if defined(__GLIBCXX__)
do_whatever();

#elif defined(_MSC_VER)
do_something_else();

#else
#warning "Default implementation might not be suitable for your platform, please check"
//OR: static_warning("Default implementation might not be suitable for your platform, please check");
//OR: static_assert(false, "Default implementation might not be suitable for your platform, please check",. true); // continue compilation

take_a_punt();
#endif


Providing all of the above might even make sense.

However we go about it, it seems the value of a #warning type feature is useful - most compilers support it - but their is no standard way to invoke it.

Thanks

David Krauss

unread,
Aug 27, 2014, 11:23:29 PM8/27/14
to std-pr...@isocpp.org
On 2014–08–28, at 5:46 AM, gmis...@gmail.com wrote:

There seems to be know standard way of issuing a warning with the expectation that compilation will continue.

We have #warning but it isn't standard.
We have static_assert but it always stops compilation.

static_assert only makes the program ill-formed, but an ill-formed program may still be used to generate an executable, as long as a diagnostic is issued. I’ve not seen any compiler terminate itself at a static_assert. The common practice is to continue analysis as with any other error.

Adding an attribute-specificier-seqopt to static_assert-declaration would allow a conforming extension [[warning]] so assertion doesn’t preclude generation of an executable.

Most programmers prefer that a successful build should not generate warnings, going so far as to use -Werror. Programs that always generate warnings even during normal compilation are troublesome.

#else
#warning "Default implementation might not be suitable for your platform, please check”

A program like this should provide the user with a means to disable the warning, such as by a #define IS_SUPPORTED, or constexpr bool is_supported = true; after checking their platform. I’d see such a “may not be suitable” message as a constant reminder to stop using that library.

gmis...@gmail.com

unread,
Aug 28, 2014, 5:30:57 PM8/28/14
to std-pr...@isocpp.org
Sorry I messed my first post right up. I'll try again.
Agreed. But the situation I want to improve on is today people are #warning because they are finding it useful but getting non standard code they think is standard because the feature is so widely available but not fully.

If we can improve on that situation by making a standard #warning/#error/#message facility that addresses the basic need plus provides override flexibility that would be the goal.

What I see is:

1. "#warning" issues a warning message, and in expected situations (being intentionally vague here) it typically results in an executable being produced.
2. In contrast, static_assert(false,"oops") issues an error message that in expected situations typically results in an executable NOT being produced.

I feel there is value in having the ability to perform aspect 1 above and so I'd like it standardized. That's my goal.
I think aspect 2 above is fine, but not enough.

"#warning"  is the most common way of doing aspect 1. and most compilers I know of provide it but notably not msvc.
so if #warning could be made standard, more code would work "as is" so this might be a way to go for that reason.

But:

we could perhaps enhance static_assert to provide the ability of 1. That might give more flexibility.

OR maybe introducing static_warning is the way.

There may be a case for all of the above they all have some virtue. People can debate any of these possibilities and we can see what pans out.

But I definitely think the ability to state an error/warning/info message and suggest the desirability of executable production in a way that could be overridden is something I'd like to see. static_assert is to strong  and #warning isn't standard or flexible enough.

But my primary goal is give people who use #warning/#pragma message a standard way to achieve what they can do today.

If we can improve on the limitations of #warning, that'd be great.

static_assert works well in macros for example. It'd be nice to get #warning to that space, for example.
I like the default error message aspect of static_assert too.

I can imagine using an enhanced static_assert  static_message or static_warning to debug some #if/#else logic paths for example.
#if WHATEVER
#else
static_assert(false, "Huh, we take this path", INFO); // remove me I am just debugging.
#endif

OR

void lift_off()
#if MSVC
do_something();
#else
static_assert(false, "Warning don't press the ignition button in testing this app. It's not implemented yet on this platform.", WARNING);
// Still want .exe produced.
#endif


Having some ability to direct the applicability of the action/message based on a constexpr bool parameter would seem desirable
The aim would be to not require macros to direct the applicability of the message/action or needing a static_if to direct such things either but still be able to use the facility in a macro easily.

Anyway, if there's any doubt of the basic goal of what I'm trying to do, lookup #warning and start there.
stackoverflow will show you that people are often trying to use this feature and are being surprised it is non standard and the workarounds are pretty ugly.

If we can standardize #warning so that makes code out their standard, or provide a better alternative as a migration path that takes some of the things that were mentioned above into account here, I think that's something worth considering, that's the goal

Thanks.

Tony V E

unread,
Aug 29, 2014, 1:56:11 PM8/29/14
to std-pr...@isocpp.org
There is nothing stopping you from writing a static_warning similar to how boost wrote BOOST_STATIC_ASSERT.  And then, once you have something working, propose it to boost and/or the committee.

The big question would be what level or warning - or do I get to decide?

Considering that warnings, of any kind, are outside the standard, it might be hard to get this beyond boost-level.

Tony

gmis...@gmail.com

unread,
Aug 29, 2014, 5:05:30 PM8/29/14
to std-pr...@isocpp.org
Hi Tony

On Saturday, August 30, 2014 5:56:11 AM UTC+12, Tony V E wrote:


There is nothing stopping you from writing a static_warning similar to how boost wrote BOOST_STATIC_ASSERT.  And then, once you have something working, propose it to boost and/or the committee.

The big question would be what level or warning - or do I get to decide?

Considering that warnings, of any kind, are outside the standard, it might be hard to get this beyond boost-level.

Tony

Well one could propose putting boost's static assert into the standard but I think we want something better than that, that isn't a macro as a starting point.

I think what we need is something that works like how #warning works as a starting point. It has reasonable definition on all compilers that implement it and there's no reason why Microsoft couldn't enable something that works similarly for their compiler.

We just don't make it a macro or #pre-processor thing.

So take that as a starting proposition and see how we can improve on it or not. It seems a step forward to a) standardize something with exactly the functionality of #warning then b) improve on it by not making it a macro and c) whatever else we think improves it further.

If people can get motivated to discuss the idea at least on a) and b) hopefully further improvement for c) will be revealed.

But #warning is clang and gcc implement it seems good, not as a macro or #pre-processor thing i.e. #pragma.
That's the starting proposition. Who is up or that and what can be done to improve things further is the other question.

John Bytheway

unread,
Sep 3, 2014, 11:35:16 PM9/3/14
to std-pr...@isocpp.org
On 2014-08-29 13:56, Tony V E wrote:

<snip>

> There is nothing stopping you from writing a static_warning similar to
> how boost wrote BOOST_STATIC_ASSERT.

Or use the existing one:

<http://www.boost.org/doc/libs/1_56_0/libs/serialization/doc/static_warning.html>

gmis...@gmail.com

unread,
Sep 4, 2014, 1:56:22 AM9/4/14
to std-pr...@isocpp.org


On Thursday, September 4, 2014 3:35:16 PM UTC+12, John Bytheway wrote:
On 2014-08-29 13:56, Tony V E wrote:

<snip>

> There is nothing stopping you from writing a static_warning similar to
> how boost wrote BOOST_STATIC_ASSERT.

Or use the existing one:

I think this all misses the point, or perhaps makes the point. It's not that we can't write one, it's that it isn't standard and it's fiddly and ugly to produce.
The fact that boost has it, and libraries like libcxx also have it too etc. indicates that it's useful and that each library shouldn't be rolling it's own.

People seem to want it and use it:

Other languages seem to find it useful too (for those that need that type of convincing) look C# felt the need to provide it:

So the basic functionality that is required is clear and the use cases are pretty clear.
It needs only to be made standard and slightly improved upon by virtue of not being a macro etc.

If we don't, people will continue to try to roll their own and have continue to have issues:

There are various arguments for and against:

One use case is that if you write a load of code and chunks aren't implemented yet, say for a particular platform, I.e. code is left with a big hole.
#if _WIN32
win32();
#elif _APPLE_
apple();
#else
HeyYouNeedToWriteThis(); /// #warning you're our only hope.
#endif

You can throw some exception at runtime, but that isn't always what you want.
You don't want to test every feature to find what you forgot to add by hoping you've caught every NotImplemented exception or whatever and printed a message at runtime.
You'd like to compile and see what's needed.
There are other use cases too it seems and even though their might be better ways to get things done, lot's of people find this way simple and intuitive.
Only to be bitten by finding out it isn't portable.

Who wants to write the kind of hacks that boost_static_warning requires each time?.
And isn't boost supposed to be the playground for determining what is useful and a candidate for standardisation. Well it has it.

So why not standardize it now?

Maybe we can also then use things like clang tidy or whatever to convert our non portable #warning code into portable static_warning code, who knows.
But we can't deprecate features easily until we have valid alternatives for them either, so give us static_warning and we get that.

Thiago Macieira

unread,
Sep 4, 2014, 1:59:51 AM9/4/14
to std-pr...@isocpp.org
On Wednesday 03 September 2014 22:56:22 gmis...@gmail.com wrote:
> One use case is that if you write a load of code and chunks aren't
> implemented yet, say for a particular platform, I.e. code is left with a
> big hole.
> #if _WIN32
> win32();
> #elif _APPLE_
> apple();
> #else
> HeyYouNeedToWriteThis(); /// #warning you're our only hope.
> #endif

This is not a good example of #warning. This is an example of #error.

This code doesn't work. You need to implement the missing function.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358

gmis...@gmail.com

unread,
Sep 4, 2014, 3:05:31 AM9/4/14
to std-pr...@isocpp.org


On Thursday, September 4, 2014 5:59:51 PM UTC+12, Thiago Macieira wrote:
On Wednesday 03 September 2014 22:56:22 gmis...@gmail.com wrote:
> One use case is that if you write a load of code and chunks aren't
> implemented yet, say for a particular platform, I.e. code is left with a
> big hole.
> #if _WIN32
> win32();
> #elif _APPLE_
> apple();
> #else
> HeyYouNeedToWriteThis(); /// #warning you're our only hope.
> #endif

This is not a good example of #warning. This is an example of #error.

Well, yes and no, it perhaps wasn't the best example, but my point was that you aren't always in a position to finish writing your application before you want yourself or others to be able to test it.
And if you don't want always to prevent generation of the whole executable and therefore eliminate any possible use of it, which #error would do because one element of functionality is missing or unavailable.
And you don't want to lose track of what you haven't written yet or have to have to exercise every element of your program to remind yourself what still needs to be implemented either.

In the end gcc, clang, and intel etc, c-sharp, boost, and libcxx have found static_warning type functionality useful and the links show other people wanting to use it and having trouble doing so and everyone is writing non-portable code to do this.

I think we should think very hard why we need them to have to do that? We are here to standardize existing practice. Is this not existing and sufficiently practiced now?
Have we better answers to all of these use cases. I haven't seen that yet.

gmis...@gmail.com

unread,
Sep 4, 2014, 3:49:29 AM9/4/14
to std-pr...@isocpp.org
I would very much like to see this standardized this.

The starting proposition is this:
* It's basically the same as boosts static_warning.
* Let's call it static_warning for now
*Think of it as being like static_assert including having a default error message.
*Specifically the user is intended to be able to direct through it if an executable/lib/target is produced or not.
*If should expected to be controllable much like #warning is controllable today on the platforms that implement it.

I'm happy to write up an initial proposal based on this starting proposition.
I don't intend to present such a paper in person though so I would need someone interested in supporting me in that. 
Any further support beyond that, in this endeavour would be great too.

Similarly, if anyone is dead against this idea, I'd like to hear from you to. Meaningful discouragement also welcome!
So basically if you really think this really is a bad idea, convince me now to stop wasting my time! :)


On Thursday, September 4, 2014 5:59:51 PM UTC+12, Thiago Macieira wrote:

David Krauss

unread,
Sep 4, 2014, 10:49:43 AM9/4/14
to std-pr...@isocpp.org, gmis...@gmail.com


On Thursday, September 4, 2014 3:49:29 PM UTC+8, gmis...@gmail.com wrote:
I'm happy to write up an initial proposal based on this starting proposition.
I don't intend to present such a paper in person though so I would need someone interested in supporting me in that. 
Any further support beyond that, in this endeavour would be great too.

I'd get behind a static_log. The term "warning" implies some level of danger, whereas the only acceptable level of danger is nil.

Tracing through templates without breaking anything is unnecessarily tricky. I want a facility that simply makes a report or log of what happened. Everyone knows that logs should never be seen by clients, except maybe with an obscure diagnostic switch. Warnings on the other hand are slightly ambiguous in that regard.

Perhaps one reason for the name of Boost static_warning is the fact that it generates an artificial problem likely to reported as a warning on each given platform. But warning of a minor problem isn't exactly the best application, nor even possible under -Werror (unless they've found something clever, which I suppose might just be beyond my imagination).

A facility specifically dedicated to logging might be more implementation effort, since it represents a new form of compiler output, but low QOI works for basic compliance (e.g., simply suppress logging under -Werror). Any effort to make template instantiation logs usable would be very nice.

gmis...@gmail.com

unread,
Sep 5, 2014, 3:23:19 AM9/5/14
to std-pr...@isocpp.org, gmis...@gmail.com
HI

On Friday, September 5, 2014 2:49:43 AM UTC+12, David Krauss wrote:


On Thursday, September 4, 2014 3:49:29 PM UTC+8, gmis...@gmail.com wrote:
I'm happy to write up an initial proposal based on this starting proposition.
I don't intend to present such a paper in person though so I would need someone interested in supporting me in that. 
Any further support beyond that, in this endeavour would be great too.

I'd get behind a static_log.

Cool. I've started writing up the issues for a draft proposal. I'll post something more detailed in the next day or two then.

static_log  or static_message seem reasonable.
 
The term "warning" implies some level of danger, whereas the only acceptable level of danger is nil.

I think the issues are a little more than that, but not a big deal.
For instance, the claim there is that the danger is nil but most #warning implementations put the word "Warning" in the message for you.  
Right there is a tension to overcome when you want a message that is or isn't a warning in your mind.
I don't think there's anything to troublesome to overcome though.

But I'll go into the options around this when I post something in the next few days and everyone can lay into that then maybe.

Jonathan Coe

unread,
Sep 5, 2014, 3:25:32 AM9/5/14
to std-pr...@isocpp.org, gmis...@gmail.com
I like static_ message
--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

Tom Honermann

unread,
Sep 5, 2014, 9:11:23 AM9/5/14
to std-pr...@isocpp.org, gmis...@gmail.com
I like static_message, static_diagnostic, or static_diagnostic_message
(though that last one is a bit long). All are in line with terminology
in the standard (C++11 1.3.6).

Tom.

On 09/05/2014 03:24 AM, Jonathan Coe wrote:
> I like static_ message
>
>
> On 5 Sep 2014, at 08:23, gmis...@gmail.com <mailto:gmis...@gmail.com>
>> <mailto:std-proposal...@isocpp.org>.
>> To post to this group, send email to std-pr...@isocpp.org
>> <mailto:std-pr...@isocpp.org>.
> --
>
> ---
> You received this message because you are subscribed to the Google
> Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to std-proposal...@isocpp.org
> <mailto:std-proposal...@isocpp.org>.
> To post to this group, send email to std-pr...@isocpp.org
> <mailto:std-pr...@isocpp.org>.

Robert Ramey

unread,
Sep 14, 2014, 2:51:57 AM9/14/14
to std-pr...@isocpp.org


On Friday, August 29, 2014 10:56:11 AM UTC-7, Tony V E wrote:

There is nothing stopping you from writing a static_warning similar to how boost wrote BOOST_STATIC_ASSERT.  And then, once you have something working, propose it to boost and/or the committee.

There is BOOST_STATIC_WARNING in the boost serialization library.  It's very fragile and always has been.  A better solution is needed. 

Robert Ramey

gmis...@gmail.com

unread,
Sep 14, 2014, 9:28:03 AM9/14/14
to std-pr...@isocpp.org, gmis...@gmail.com
Hello everyone,

I don't have a dropbox account, but here's some more details, references and rationale for this static_warning feature.
Feedback please for next steps towards a proper proposal.

Static Warning/Message

Developers like the ability to generate their own compiler warnings and messages:
http://embeddedgurus.com/stack-overflow/2011/09/effective-c-tip-9-%E2%80%93-use-warning/

If you haven't clicked, the most common way to do it this:
#warning "Standardization is long periods of mind-numbing boredom interrupted by moments of sheer terror..."

The above statement generates the rather boring message of:
test.cpp:1:1: Warning: ... Well, you get the idea.

If you are new to #warning, you might find it is similar to static_assert, yet strangely different...
Both display a user defined message. The useful difference is that with #warning the build typically succeeds (i.e. the target will be generated) but with static_assert the build typically fails.

#warning is so popular that most vendors already support it:

Even Microsoft support it:
http://msdn.microsoft.com/en-us/library/963th5x3.aspx
Just not in Visual C++...

Implementations of #warning are pretty consistent. EDG says this:
"The non-standard preprocessing directive #warning is supported. It is similar to the #error directive, but
results in a warning instead of a catastrophic error when processed. This directive is not recognized in strict mode.
(This is an extension found in GNU C compilers.)
The details vary slightly, but usability and functionality of #warning is consistent in all implementations I've seen."

#warning is so widespread people often use it for years before discovering it's not standard. This is a pain.
stackoverflow is littered with requests for making the feature. Often spreading more incompatibility in the process...

When #warning is not available, people (even smart ones) go to great lengths to re-invent it. Even those that have yet to invent it, re-invent it:
http://support.microsoft.com/kb/155196




Boost's static warning listed above expects an expression instead of a message, but the concept is the same.
Boost says this about it:
"BOOST_STATIC_WARNING(x), generates a compile time warning message if the integral-constant-expression x is not true.
Note that if the condition is true, then the macro will generate neither code nor data - and the macro can also be used at either namespace, class or function scope. When used in a template, the expression x will be evaluated at the time the template is instantiated; this is particularly useful for validating template parameters.
It is intended that the functioning of BOOST_STATIC_WARNING(x) be identical to that of BOOST_STATIC_ASSERT(x) except that rather than resulting in a compilation error, it will result in a compiler warning. In all other respects it should be the same. So for more information on using BOOST_STATIC_WARNING(x) consult the documentation for BOOST_STATIC_ASSERT(x)"

So basically it's #warning with a default message and an interface more consistent with static_assert. Good idea...

Let's recap:
- User defined warnings are popular.
- They have been widely implemented across multiple platforms and pretty consistently too.
- #warning semantics are the most common type of usage.
- But boost semantics are also popular and more flexible.
- Users keep re-implementing this feature (with difficulty) when it's are not available.
- #warning and boost static warning seem to point the way for both what we need and what we need to support.

Proposal: Unify #warning and boost static warning to achieve all of the above. We need. static_warning(expr, msg) See option #4 below..
People like this idea so much, they'll even pay for it!
http://stackoverflow.com/questions/8936063/does-there-exist-a-static-warning

So, the goals of this proposal are:
1. Justify the value in user defined warnings.
2. Suggest a few options to support getting user defined warnings accepted as a Standard feature.
3. Propose a solution with an interface that works for both #warning and boost static warning, so they both can migrate to Standard code:
4. Collect that small reward. :)

Options in more detail:

Option #1: Try to standardize #warning as is.

#warning implementations are close enough that this might be possible. Most implementations are compatible but differences can be found around the parsing of quotes in the string after #warning. Single, double, or no quotes can be a problem but there is a lot of compatibility here still.
It might be possible for Vendors to converge on a Standard pattern for #warning because code that is broken by any change should be loud and fixing it should be easy and mechanical and any unfixed "breakages" might be just cosmetic or not important enough to worry about, as it is a warning after all...

Pros: This option could make a lot of existing code Standard "as is". Requires no new keywords.
Cons: Small risk to existing code but why do this if #warning might be better if it wasn't a #pre-processor feature anyway.

A major con of this route is it doesn't help boost static warning users at all nor offer consistency with static_assert.
For this reason this option isn't recommended as a sole action.

Option #2: Introduce static_warning(message) as a new non pre-processor keyword as an exact model of #warning.

Pros: Like option #1 but without risk to existing code and not a pre-processor solution.
Cons: Doesn't help boost static warning users at all. Doesn't help consistency with static_assert. Requires a new keyword.

This option isn't recommended because the interface is inflexible and the pre-processor is still effectively always required to manage when the warning should occur.

Option #3: Standardize BOOST_STATIC_WARNING(expr) "as is" as static_warning(expr).

Pros: More like static_assert. Helps boost users move to Standard code.
Cons: Doesn't suit #warning users as it loses their message. Introduces a new keyword.

Option #4: Combine #warning and boost's static_warning as: static_warning(expr, msg)

Propose #warning "msg" users migrate to use static_warning(false, "msg")
Propose BOOST_STATIC_WARNING(x) users migrate to use static_warning(expr) with a default message like static_assert.
Consider if static_message(expr,msg) is also of value. See below.

Pros: Gives both #warning and BOOST_STATIC_WARNING users an easy migration path to Standard code. Consistent interface.
Cons: New keyword. If informaitonal messages were required also, a static_message(expr, msg) would also need to be proposed.

Option #5 - Extend static_assert to support warnings and possibly messages too.
We have: static_assert(expr) and static_assert(expr, msg).
We could add: static_assert(expr, msg, kind = assert_kind::error);
e.g. enum class assert_kind { error, warning /*, info, note*/ };

When assert_kind::warning is specified, the compiler will work like #warning/static_warning in option #4. rather than the classic static_assert.
assert_kind::info and assert_kind::note could be additional options provided as not every type of message a developer wants to generate is really a "warning". assert_kind::note might be a message considered part of a previous error, warning or info message.

Pros: All the pro's of option #4. Requires no new keyword. Possibly the most flexible option.
Cons: Interface more complicated that straigh Option #4's static_warning(expr,msg).

Conclusion:
Recommend Option 4 or 5, based on:
It seems important to give users the opportunity to avoid the pre-processor.
It seems essential to support both #warning users and boost static warning users.
It seems making the feature consistent with static_assert makes it easier to learn.
Option 4 seems easier to use but option 5 might be more flexible and introduces no new keywords.
Option 1 could be done in addition to the proposed option though this isn't proposed.

Todo:
- consider if example use cases useful, but links above have some use cases already.
- consider narrowing down proposal, with particular regard to only presenting options to 4 or 5, based on feedback.
- integrate general feedback on op5ions 4, or 5
- solicit value proposition and details of static_message /  assert_kind::info and assert_kind::note in interface as separate feature aspect of static_warning
- include references to standard, and static_assert etc.

Nicola Gigante

unread,
Sep 14, 2014, 11:52:25 AM9/14/14
to std-pr...@isocpp.org, gmis...@gmail.com

Il giorno 14/set/2014, alle ore 15:28, gmis...@gmail.com ha scritto:

> Hello everyone,
>
> I don't have a dropbox account, but here's some more details, references and rationale for this static_warning feature.
> Feedback please for next steps towards a proper proposal.
> [cut]

Hello.

I’m quite an outsider in this list but I would like to express my opinion.
There’s something quite misleading I see in your summary of the intended proposal,
namely the association between #warning and static_assert.

You list the non-standard alternatives of #warning, #pragma message and so on, and then
you list BOOST_STATIC_WARNING.
You say BOOST_STATIC_WARNING is about “#warning but with an interface more similar to static_assert()”,
but it’s not totally correct. It’s not a matter of interface, it’s a matter of capabilities of the feature.

#warning is a preprocessor directive, perfectly similar to #error, and talks about messages generated in
the preprocessing phase.

static_assert(), on the other hand, gets evaluated a lot later in the chain, and can be used to detect
errors during the compilation. It’s an entirely different beast.

People use the non-standard #warning directive to warn about unimplemented features in headers
on unsupported platforms or missing macro definitions or things like that, while an hypothetical
static_message() similar to static_assert() would enable the code to talk its users about template
parameters, types etc…

I know everybody on this list knows the difference between this concepts and I don’t feel like I
need to explain them better.
My point is that it’s not at all clear what this proposal is about. A standard #warning preprocessor
directive, or a compile-time static_message(), similar in principle to static_assert()?

My personal feeling is that standardizing the common practice of #warning could be very reasonable,
given the broad support of this extension. static_message() could be useful too, but I think it should
be proposed together with a revision of the limits of static_assert() (the possibility to compute
at compile time the message instead of being limited to a literal, etc…)

Bye,
Nicola

gmis...@gmail.com

unread,
Sep 14, 2014, 5:25:29 PM9/14/14
to std-pr...@isocpp.org, gmis...@gmail.com
Hi Nicola


On Monday, September 15, 2014 3:52:25 AM UTC+12, Nicola Gigante wrote:


Hello.

I’m quite an outsider in this list but I would like to express my opinion.
There’s something quite misleading I see in your summary of the intended proposal,
namely the association between #warning and static_assert.

Ok, I'm happy to try to fix that that if that's the case.

You list the non-standard alternatives of #warning, #pragma message and so on, and then
you list BOOST_STATIC_WARNING.
You say BOOST_STATIC_WARNING is about “#warning but with an interface more similar to static_assert()”,
but it’s not totally correct. It’s not a matter of interface, it’s a matter of capabilities of the feature.

#warning is a preprocessor directive, perfectly similar to #error, and talks about messages generated in
the preprocessing phase.

static_assert(), on the other hand, gets evaluated a lot later in the chain, and can be used to detect
errors during the compilation. It’s an entirely different beast.


I agree mostly except in the conclusion, I'm not sure I agree it's entirely different beast for practical purposes.
But I'll see how your argument evolves.
 
People use the non-standard #warning directive to warn about unimplemented features in headers
on unsupported platforms or missing macro definitions or things like that, while an hypothetical
static_message() similar to static_assert() would enable the code to talk its users about template
parameters, types etc…

Let's see if we can get to the heart of your issue like this: Now that we have static_assert. Is the ever a case where you will use #error that you can't use static_assert instead? 


I know everybody on this list knows the difference between this concepts and I don’t feel like I
need to explain them better.
My point is that it’s not at all clear what this proposal is about. A standard #warning preprocessor
directive, or a compile-time static_message(), similar in principle to static_assert()?

My personal feeling is that standardizing the common practice of #warning could be very reasonable,
given the broad support of this extension. static_message() could be useful too, but I think it should
be proposed together with a revision of the limits of static_assert() (the possibility to compute
at compile time the message instead of being limited to a literal, etc…)

I agree in as much as that I put standardizing #warning as a possibility and better than nothing but not my preferred option and certainly not if it's the only thing done. I see boost type static warning as just as useful but see that if extended, it makes #warning unnecessary.

Do you disagree with that latter idea and how. And what can I add to the text to make you more happy with it.
The limits of static_warning in evaluating the expression and the content of the message are that of static_assert.
I'm keen to ride on the coat tails of that definition than express something differently or even at all depending on what options we are talking about here.
 

Bye,
Nicola

Nicola Gigante

unread,
Sep 16, 2014, 3:28:15 AM9/16/14
to std-pr...@isocpp.org

Il giorno 14/set/2014, alle ore 23:25, gmis...@gmail.com ha scritto:

> Hi Nicola
>

Hi!

> I agree mostly except in the conclusion, I'm not sure I agree it's entirely different beast for practical purposes.
> But I'll see how your argument evolves.
>

They are indeed. You don’t catch wrong template parameters with #warning.
And the happen at completely different stages of compilation. They’re
completely different in the same way as #if is completely different
from std::conditional<>.

>
> Let's see if we can get to the heart of your issue like this: Now that we have static_assert. Is the ever a case where you will use #error that you can't use static_assert instead?

Of course static_assert is more general.

#ifndef SOMEPLATFORMMACRO
#error This platform is not supported
#endif

You could change it to:
static_assert(SOMEPLATFORMMACRO, “You get the idea”);

But you don’t get the same behavior. #error stops the preprocessing
phase, so the compiler doesn’t bother with anything that could be
wrong in the code (and if you’re quitting because your platform is
unsupported, a lot of things are broken down there). If you replace
the #error with the static_assert you get the same error message but
the compiler have to parse the code, so you get flooded with a whole
bunch of other errors that confuse the user and hide the real problem.

This is not the case with #warning and static_message(), since they would
not stop the compilation either way, but since you asked about static_assert
I’ve answered.

>
> I agree in as much as that I put standardizing #warning as a possibility and better than nothing but not my preferred option and certainly not if it's the only thing done. I see boost type static warning as just as useful but see that if extended, it makes #warning unnecessary.
>
> Do you disagree with that latter idea and how. And what can I add to the text to make you more happy with it.
> The limits of static_warning in evaluating the expression and the content of the message are that of static_assert.
> I'm keen to ride on the coat tails of that definition than express something differently or even at all depending on what options we are talking about here.

I completely agree that a static_message() facility would be more useful in general than #warning. The point is that
they’re different things and should be dealt with in different discussions. If you want to extend the language by
adding the capability of printing a message during compilation to warn the user about dubious things at compile time,
to complement static_assert(), than propose static_message().

If you want to propose the standardization of a common and widespread extension, thus making compliant a ton
of existing code out there, than propose #warning.

I think both have merits and I would be happy the see them in the next standard. But I would not be completely satisfied by
the inclusion of static_message() but not of #warning, only on the basis that the latter is reducible to the former, because
I would like to see the ton of code already using #warning becoming conforming code.

Bye,
Nicola

gmis...@gmail.com

unread,
Sep 16, 2014, 5:52:10 AM9/16/14
to std-pr...@isocpp.org
Hi Nicola

Of course static_assert is more general.

#ifndef SOMEPLATFORMMACRO
#error This platform is not supported
#endif

You could change it to:
static_assert(SOMEPLATFORMMACRO, “You get the idea”);

But you don’t get the same behavior. #error stops the preprocessing
phase, so the compiler doesn’t bother with anything that could be
wrong in the code (and if you’re quitting because your platform is
unsupported, a lot of things are broken down there). If you replace
the #error with the static_assert you get the same error message but
the compiler have to parse the code, so you get flooded with a whole
bunch of other errors that confuse the user and hide the real problem.

This is not the case with #warning and static_message(), since they would
not stop the compilation either way, but since you asked about static_assert
I’ve answered.

ok, I agree.
 
I completely agree that a static_message() facility would be more useful in general than #warning. The point is that
they’re different things and should be dealt with in different discussions. If you want to extend the language by
adding the capability of printing a message during compilation to warn the user about dubious things at compile time,
to complement static_assert(), than propose static_message().

If you want to propose the standardization of a common and widespread extension, thus making compliant a ton
of existing code out there, than propose #warning.

I think both have merits and I would be happy the see them in the next standard. But I would not be completely satisfied by
the inclusion of static_message() but not of #warning, only on the basis that the latter is reducible to the former, because
I would like to see the ton of code already using #warning becoming conforming code.

Bye,
Nicola

Yes, that's my goals:

1. make code that is using #warning Standard somehow
2. make code that is using BOOST_STATIC_WARNING Standard somehow.

I don't care if that happens directly or indirectly. By that I mean, I don't care if they become Standard "as is" or have a simple mechanical upgrade paths to some other feature that is Standard.

I'm happy that be one proposal or into two if that's the consensus which I'm hearing is your preference.

It seems you voting on:

1. Make #warning Standard so some errors can get reported on in the pre-processing phase where that is wanted.
2. Introduce static_warning(expr,msg) too so errors can get reported after the pre-processing phase and in a more flexible way.

That achieves both my goals.

I'm less sure what you may be saying about static_message.

My position on it is that is, conceptually a static_warning and a static_message feature are two very similar but different things.

At the simplest level, I anticipate the compiler processing static_warning and desiring to stick 'Warning' in the message for you not that it has to, but that it could. but you also might want to report a version number or some debug info in your code which isn't a warning really, in that instance a static_message type feature is what you'd want and there the compiler would be encouraged to NOT put 'Warning' in the message.

static_warning is the essential and useful feature. But I see value in both.

I'm keen to try to resolve the terminology and use cases to something that is clear in everyone's minds.

At a more complex level, static_warning can be effected by other options like compile with no warnings. Where a static_message feature would be enabled/disabled by other options. This further shows the distinction.

In summary I'm hearing/seeing:
Make #warning standard roughly "as is". Introduce static_message(expr,msg) to cover BOOST_STATIC_WARNING(expr).
Tbd. on value of static_message

Put #warning in one proposal, static_warning in another with perhaps static_message as a sub part of that second proposal.

How do you feel about that?

Thanks

Nicola Gigante

unread,
Sep 16, 2014, 6:36:04 AM9/16/14
to std-pr...@isocpp.org
Il giorno 16/set/2014, alle ore 11:52, gmis...@gmail.com ha scritto:

Yes, that's my goals:

1. make code that is using #warning Standard somehow
2. make code that is using BOOST_STATIC_WARNING Standard somehow.

I don't care if that happens directly or indirectly. By that I mean, I don't care if they become Standard "as is" or have a simple mechanical upgrade paths to some other feature that is Standard.

I'm happy that be one proposal or into two if that's the consensus which I'm hearing is your preference.

It seems you voting on:

1. Make #warning Standard so some errors can get reported on in the pre-processing phase where that is wanted.
2. Introduce static_warning(expr,msg) too so errors can get reported after the pre-processing phase and in a more flexible way.

That achieves both my goals.

I'm less sure what you may be saying about static_message.

My position on it is that is, conceptually a static_warning and a static_message feature are two very similar but different things.

At the simplest level, I anticipate the compiler processing static_warning and desiring to stick 'Warning' in the message for you not that it has to, but that it could. but you also might want to report a version number or some debug info in your code which isn't a warning really, in that instance a static_message type feature is what you'd want and there the compiler would be encouraged to NOT put 'Warning' in the message.

static_warning is the essential and useful feature. But I see value in both.

I'm keen to try to resolve the terminology and use cases to something that is clear in everyone's minds.

At a more complex level, static_warning can be effected by other options like compile with no warnings. Where a static_message feature would be enabled/disabled by other options. This further shows the distinction.

In summary I'm hearing/seeing:
Make #warning standard roughly "as is". Introduce static_message(expr,msg) to cover BOOST_STATIC_WARNING(expr).
Tbd. on value of static_message

Put #warning in one proposal, static_warning in another with perhaps static_message as a sub part of that second proposal.

How do you feel about that?

I feel perfectly fine!

Please note, about the “voting” thing: In the standardization process I’m exactly Mr.Nobody,
do I’m not voting anything… Mine were just opinions from a C++ developer point of view.

About the static_message/static_warning difference: you’re completely right that they’re different
in scope, especially regarding the options available in some implementations that are used to
see warnings as errors.

static_warning() could be very useful, but keep in mind that a generic static_message(), capable of
printing informations calculated at compile-time instead of a simple literal, would be a panacea
for debugging of template metaprogramming code, which is currently a pain. If static_message()
gets this capability I don’t see why not to extend it to static_assert() and static_warning() of course.

Maybe it is worth considering a more general effort to enhance the static_whatever() architecture to
allow a more flexible compile-time communication from library developers to library users.


Thanks
Thanks to you,
Nicola

Matthew Woehlke

unread,
Sep 18, 2014, 7:12:01 PM9/18/14
to std-pr...@isocpp.org
On 2014-09-14 09:28, gmis...@gmail.com wrote:
> [tl;wq]

My 2¢... standardizing #warning would be good, but I'd reiterate much of
what Nicola has said, i.e. that IMO this can/should be separate and in
addition to a static_assert-like diagnostic. (Although... it's not quite
the same dichotomy as static_assert/#error, since a #warning, being
normally non-fatal, won't stop compilation, and thus the argument about
it popping earlier is less relevant.)

That said... I'd go with static_diagnostic<expr, msg, type>, where expr
and msg are just what you'd think, and type is e.g. error, warning, ...
Ideally static_assert<expr, msg> would then be a "shortcut" for
static_diagnostic<expr, msg, ERROR> (for however we prefer to spell
"ERROR"). Using "diagnostic" seems most consistent with existing
practice e.g. gcc's #pragma diagnostic and provides greater flexibility
(for one, preprocessor defines at least can change the diagnostic
level). Bonus points if 'type' itself can somehow be conditional (e.g.
contain a constexpr expression yielding a type).

Additional bonus points if the expr part can be optional. (I'd think
this is possible; it's just an overload problem between (bool, char*,
enum) and (char*, enum); those shouldn't normally be ambiguous.)

My second choice would be the above but use static_assert instead of
static_diagnostic, with the type optional.

p.s. If there is any specification of prefix strings, I'd prefer stating
that they are consistent with other diagnostics of the same type (e.g.
gcc/clang use "warning: "; note the lower case). The goal should be that
downstream tools (IDE's, build bots, etc.) should not need to change
their recognition rules to recognize the warning as such.

p.p.s. When you mentioned version numbers, I had a sudden thought that
you could leverage this to use the compiler as a sort of handy, always
available general purpose "scripting" engine. (Limited to things you can
do with constexpr, of course, but still, I could imagine this being
useful.) It might be a helpful debugging aid also, especially as I
imagine it would be parsed for every template instantiation, e.g. to see
what template instantiations are happening or otherwise inspect the
compile state when things are going screwy.

--
Matthew

Douglas Boffey

unread,
Sep 20, 2014, 11:56:57 AM9/20/14
to std-pr...@isocpp.org, gmis...@gmail.com


On Sunday, 14 September 2014 14:28:03 UTC+1, gmis...@gmail.com wrote:

Option #5 - Extend static_assert to support warnings and possibly messages too.
We have: static_assert(expr) and static_assert(expr, msg).
We could add: static_assert(expr, msg, kind = assert_kind::error);
e.g. enum class assert_kind { error, warning /*, info, note*/ };

I would like to see fatal as another option to assert_kind.  There are cases where it would be inappropriate to do error recovery (e.g. due to the compiler) but the necessary information would not be available to the preprocessor for #error.
Reply all
Reply to author
Forward
0 new messages