diagnosing "unused" variables that are only constructed

瀏覽次數:178 次
跳到第一則未讀訊息

gmis...@gmail.com

未讀,
2017年10月11日 晚上7:09:472017/10/11
收件者:ISO C++ Standard - Future Proposals

I had this thought from reading one of the other threads on here:


The following code compiles by default without warning.

#include <string>

int main()
{
    std::string s;
}


This code also compiles without warning:


#include <cstdio>
#include <iostream>

struct Whatever
{
    int z;
    Whatever() { z = 0; std::cout << "Whatever!\n"; }
};
int main()
{
    Whatever x;
}

It seems constructing a named object and then not calling any methods on it usually represents "non use" and is usually a programmer mistake.

If the compiler could diagnose this "non use", it would be useful so programmers could clean up their code.

But as construction may serve an essential purpose, a warning on this may be bogus. lock_guard springs to mind as an example of that.

However, I would think in the vast majority of cases, construction only is a mistake and std::string seems like a poster child for that.

Can we improve on this situation so that the example code can be diagnosed more trivially?

Suggestion:

Can we do something like mandate that the compiler can warn about potential non use of an object if it is constructed but no methods on it are called on it, unless the constructor is marked to state that construction only is meaningfull?

i.e.:

struct Whatever
{
    int z;
    Whatever() [[construction_only_of_use]] { z = 0; std::cout << "Whatever!\n"; }
    // If applied to the struct then however this type is constructed,
    // it will be diagnosed as unused if no methods are called on it.
};

int main()
{
    Whatever x; // Diagnose as unused. Use [[construction_only_of_use]] to prevent.
}


There might need more definition here as to what counts as "use" (i.e. also don't diagnose if we take the address of the variable or whatever) but it seems the essential idea is viable.

I think the compiler could be instructed to optimize away objects that are constructed but "not used" by this definition though I don't imagine doing it aggressively by default or presently, but in the future this may be more practical.

Before that can happen I think existing code would need to be updated with the attribute I described above. std::lock_guard would be an example of such a class, in order that no bogus warnings are issued.

But the value is that accidental declaration and non use of std::string would be an example of something I think this feature would catch frequently.

This warning could be on by default once we have the tools to prevent bogus diagnosis of unused variables. For now, by default I would expect the compiler to be conservative about optimizing such "unused" variables. But perhaps in the future it could be aggressive about such optimization once the tools to find and fix our mistakes and mark our intent have been in place for a while.

If we can already control construction only issues like I have described, I am not aware of how.


Thoughts?

gmis...@gmail.com

未讀,
2017年10月11日 晚上11:16:282017/10/11
收件者:ISO C++ Standard - Future Proposals
Re-reading my previous post I feel some of it could be clearer.

What I'm suggesting is providing tools so that code like this: int main() { std::string s; } can generate some kind of "object 's' appears unused" compiler warning, with no effort from the class author or user on the basis that patterns like this usually indicate a mistake but the compiler can't tell that unless we tell it.

The goal is to enable *the user* to find and remove such code (in this case 's') as it improves code clarity as well as code performance and C++ is striving for both.

We can't do this already (I assume) because classes like std::lock_guard invite a construction only pattern. So I'm suggesting we decorate those types or their constructors to say "construction only is ok". Once decorated, warnings of "unused" instances of those classes will vanish.

Once the std::lock_guard type of classes are correctly identified, I expect most of the remaining warnings will be identifying a mistake of leaving an object constructed that they aren't using any more. Where the warning is correct, the user will delete that code and the warning will cease because of that.

Where the warning is not appropriate for some instance because the user wants just construction, I'm suggesting they annotate that statement to say that to silence the warning. I'm suggesting using the an attribute of[[construction_only_of_use]] again for that.

The use of attributes and the exact names is not important here so much as the idea of diagnosing errant use of constructed but otherwise unused objects. I think most struct/class objects fit that mould so this feature would catch a lot of mistakes.

Objects that are reported "maybe unused" will still have code generated for them (if the compiler was going to) so the idea is that these warning are always "safe" so can be on by default.

The main aim of this feature is to by default enable us to find code that we don't mean to exist so that *we* can remove it from our source code so it's clearer and faster and if we do "nothing" in response no harm is done.

But I think this model also opens a path to enable more diagnosis and optimization opportunities and with more chance of them being correct such that eventually we could have an optimization that just removes any constructed but otherwise unused objects and down the line maybe have that on by default.

Ray Hamel

未讀,
2017年10月12日 上午11:56:272017/10/12
收件者:ISO C++ Standard - Future Proposals
Compilers are already smart enough to optimize away code that never performs I/O, such as your example with std::string. https://godbolt.org/g/3mKNwn

-Ray

Patrice Roy

未讀,
2017年10月12日 下午2:30:532017/10/12
收件者:std-pr...@isocpp.org
I'd rather leave this "issue" alone; in systems where symmetrical behavior is required (loading a DLL / unloading it, for example), a simple way to automate unloading is using the destructor of a local (named) variable and let RAII work its magic. If a compiler warns about it at high warning levels, let it, but I'd keep the standard's text away.

2017-10-12 11:56 GMT-04:00 Ray Hamel <rayg...@gmail.com>:
Compilers are already smart enough to optimize away code that never performs I/O, such as your example with std::string. https://godbolt.org/g/3mKNwn

-Ray

--
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/3e025662-c9e5-4e62-be32-2bf67b6be143%40isocpp.org.

Matthew Woehlke

未讀,
2017年10月12日 下午2:42:512017/10/12
收件者:std-pr...@isocpp.org、gmis...@gmail.com
On 2017-10-11 19:09, gmis...@gmail.com wrote:
> It seems constructing a named object and then not calling any methods on it
> usually represents "non use" and is usually a programmer mistake.
>
> If the compiler could diagnose this "non use", it would be useful
> so programmers could clean up their code.
>
> But as construction may serve an essential purpose, a warning on this may
> be bogus. lock_guard springs to mind as an example of that.

I've had this discussion before. Right around when [[nodiscard]] was
being standardized IIRC, I tried to argue that it is the wrong
attribute; what we really need is "this object must not be immediately
destroyed" and "the user must *do something* with this object".

> Can we do something like mandate that the compiler can warn about potential
> non use of an object if it is constructed but no methods on it are called
> on it, unless the constructor is marked to state that construction only is
> meaningfull?
> [...]
> There might need more definition here as to what counts as "use" (i.e. also
> don't diagnose if we take the address of the variable or whatever) but it
> seems the essential idea is viable.

Er... well... as I recall, exactly that was the sticking problem in the
earlier conversation.

I suspect that the correct answer probably amounts to "a branch in the
code depended on the value of at least one member in <object-specific
set of members>". (IOW, sort of a converse of valgrind's "conditional
expression depends on value of uninitialized bytes".) That's hard to
specify. And it's worse when you only need to care #ifdef _DEBUG.

...of course, that's also why we have [[maybe_unused]]...

--
Matthew

Jan Wilmans

未讀,
2017年10月12日 下午3:18:422017/10/12
收件者:std-pr...@isocpp.org、gmis...@gmail.com
My 'proposal draft' for unnamed variables would express this intent, of having deliberately created an object with automatic lifetime, so the sole purpose of construction and destruction, properly.




--
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.



--
Met vriendelijke groeten,

Jan Wilmans

gmis...@gmail.com

未讀,
2017年10月12日 下午4:23:202017/10/12
收件者:ISO C++ Standard - Future Proposals、gmis...@gmail.com

Er... well... as I recall, exactly that was the sticking problem in the
earlier conversation.

I suspect that the correct answer probably amounts to "a branch in the
code depended on the value of at least one member in <object-specific
set of members>". (IOW, sort of a converse of valgrind's "conditional
expression depends on value of uninitialized bytes".) That's hard to
specify. And it's worse when you only need to care #ifdef _DEBUG.



I expect to find a sticking point in this area again and it may well be those people arguing for no change are right.

But right now, my non expert view is that the compiler and only spot use, but what actually counts as use and valid use?

In my simple tests, MSVC (and gcc) did not warn that the string variable in my example was "unused". *The question is why?*

And remember my goal is code clarity more than performance, because my aim is to warn that the string is unused so I as a programmer can remove the bogus variable from my program and improve clarity.

Optimization is secondary to this i.e. if the compiler optimized the code away, I care less about that fact, other than to note that if it was able to, why was it not able to warn me so I can clean up my source code not just have by executable cleaner?

I'm not sure myself if optimizing that results in the whole code being removed implies the compiler noticed in a more straight forward way that the object was unused so it can warn. It might just have happened that various passes of optimization picked away at it code to get the result so that's why it was unable to warn. So the reason why there was no warning for my example is of interest to me.

But my thinking at the moment is the compiler cannot get us where we want because it can't know what counts as use so we need to tell it with attributes or some such thing.

You mentioned  "branch in the
code depended on the value of at least one member in <object-specific
set of members>" but is that enough, because my thought are:

But whose branches should the compiler be looking at?
Branches in the constructor itself on it's own members happen. We are probably not getting a warning for my example because the compiler is counting the object's own use of itself in the constructor as use.

To my mind, in any case, constructors will do useful things that may or may not be considered 'use' from a technical point.

But regardless, it is a design issue if "construction only" is desirable or not. I don't see how the compiler can know.

For example, if I start building a house, I can lay the foundations. (Call that construction for my purposes), and then never go on to build the house. In the real world that's probably means someone has forgotten to finish the job, but technically the land has been used.

Another example, in my app I might declare a dialog box class instance, but if nowhere in my code exists some kind of Show() call, the chances are I'm not using the dialog box any more but I've just forgotten to remove it from my code.
 
If the compiler doesn't choose to warn me, then that dialog or string declaration is stuck in my source code, even if it is optimized away at runtime. But how can it know what to do, because in the case of lock_guard, I want this result. I'm not sure how the compiler can spot the difference unless I tell it because it seems it's a design thing?

In summary, the answers to these questions might help my thinking at least on this:
1. why is the compiler not warning me my string is 'unused' in my simple example code.
2. is it because it's seeing the strings own use in it's constructor as definitive 'use' so not warning?
3. If this is why, looking at outside use probably isn't enough, because things like lock_guard have no outside use by design. So how is it going to get the answer I want if we don't help it?

That's a long reply, but I hope that relates to your branches comment in the way you were thinking.

Thanks

gmis...@gmail.com

未讀,
2017年10月12日 下午4:25:522017/10/12
收件者:ISO C++ Standard - Future Proposals、gmis...@gmail.com

Hi Jan

As best I can tell, your proposal is solving a different problem? See my reply to Matthew that might reveal to you if this is a true statement or not.
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.

gmis...@gmail.com

未讀,
2017年10月12日 下午4:27:102017/10/12
收件者:ISO C++ Standard - Future Proposals
See my reply to Matthew. But I'm not so much interested in are they smart enough to optimize it away, but why aren't they smart enough to tell me so I can optimize it away.

gmis...@gmail.com

未讀,
2017年10月12日 下午4:42:432017/10/12
收件者:ISO C++ Standard - Future Proposals


On Friday, October 13, 2017 at 7:30:53 AM UTC+13, Patrice Roy wrote:
I'd rather leave this "issue" alone; in systems where symmetrical behavior is required (loading a DLL / unloading it, for example), a simple way to automate unloading is using the destructor of a local (named) variable and let RAII work its magic. If a compiler warns about it at high warning levels, let it, but I'd keep the standard's text away.

In my suggested idea, your use case would be fine, except the compiler will warn you if that's what you meant and force you to use an attribute to state that to get rid of the warning. Since you can put the attribute at the class level, the author is making it clear this is a design issue, so the users of the class need do nothing. This sounds an exact fit for your use case.

Your message suggests your concern is mainly about optimizing though. Note my proposal does not suggest affecting any optimization by default, so your code is safe regardless of any warning that might be issued.

Matthew Woehlke

未讀,
2017年10月12日 下午5:03:072017/10/12
收件者:std-pr...@isocpp.org、gmis...@gmail.com
On 2017-10-12 16:23, gmis...@gmail.com wrote:
> In my simple tests, MSVC (and gcc) did not warn that the string variable in
> my example was "unused". *The question is why?*

...because it has a non-trivial ctor/dtor, which *may* be all you cared
about. Current compilers are not smart enough to distinguish between
such reasonable uses (e.g. if you'd used a lock_guard, it would be okay
that you didn't do anything else with it) and when you should have done
something more to "use" the object, nor does there exist a way to tell
the compiler which case is correct for the type. Thus, they err on not
spamming you with false positives.

> But regardless, it is a design issue if "construction only" is desirable or
> not. I don't see how the compiler can know.

We would need an attribute or something. Without that, the compiler
"must" assume that it is okay to merely construct and destroy the
object. (When I say "must"... it *could* make the opposite assumption,
but this would produce false positives, and vendors have historically
chosen to warn too little rather than too much. "Must" implies the
assumption that this choice will remain unchanged.)

--
Matthew

gmis...@gmail.com

未讀,
2017年10月12日 下午5:15:142017/10/12
收件者:ISO C++ Standard - Future Proposals、gmis...@gmail.com


We would need an attribute or something. Without that, the compiler
"must" assume that it is okay to merely construct and destroy the
object. (When I say "must"... it *could* make the opposite assumption,
but this would produce false positives, and vendors have historically
chosen to warn too little rather than too much. "Must" implies the
assumption that this choice will remain unchanged.)

--
Matthew

Well that's what my suggestion calls for. So it sounds then like we are agreeing?

Matthew Woehlke

未讀,
2017年10月12日 下午5:39:222017/10/12
收件者:std-pr...@isocpp.org、gmis...@gmail.com
On 2017-10-12 17:15, gmis...@gmail.com wrote:
> On 2017-10-12 16:23, gmis...@gmail.com wrote:
>> We would need an attribute or something. Without that, the compiler
>> "must" assume that it is okay to merely construct and destroy the
>> object. (When I say "must"... it *could* make the opposite assumption,
>> but this would produce false positives, and vendors have historically
>> chosen to warn too little rather than too much. "Must" implies the
>> assumption that this choice will remain unchanged.)
>
> Well that's what my suggestion calls for. So it sounds then like we are
> agreeing?

We agree close enough... the devil is in the details. It's specifying
"how" this feature works that has historically prevented any such
proposal from moving forward.

I suppose you could propose a new attribute that says "it's okay to
construct this object and do nothing else with it" (I'd go that way
because those are less common), with the obvious intention being that
compilers "ought to" complain if you construct an object of some other
type and then don't use it. This could be combined with [[nodiscard]] to
say that "you need to do something with this, but just sticking it in a
named variable is sufficient".

That *might* work. Or... it might not. If not, it will probably be
because there is no agreed-upon definition of what constitutes "using
the object". That's been the sticking point, historically.

--
Matthew

Nevin Liber

未讀,
2017年10月12日 下午5:40:422017/10/12
收件者:std-pr...@isocpp.org、gmis...@gmail.com
You want opt-out, which will generate far too many false positives on existing, working code.  For many businesses, changing existing, working code has a very non-trivial cost.

If it were opt-in, do [[maybe_unused]] and [[nodiscard]] already cover it?
--
 Nevin ":-)" Liber  <mailto:ne...@eviloverlord.com>  +1-847-691-1404

janwi...@gmail.com

未讀,
2017年10月12日 下午5:46:522017/10/12
收件者:ISO C++ Standard - Future Proposals、gmis...@gmail.com
What I was suggesting is that by introducing a syntax to explicitly make something unnamed, the compiler would then be free to emit warnings for all other cases where an object is not referenced after construction, without needed to evaluate whether the constructor/destruction has side-effects or not.

This is what you wanted right?
On the other hand, I don't really see the value in putting that specific warning in the standard itself, but any compiler would be free do to do it and it would be easier to implement.

janwi...@gmail.com

未讀,
2017年10月12日 下午5:54:072017/10/12
收件者:ISO C++ Standard - Future Proposals、gmis...@gmail.com

If it were opt-in, do [[maybe_unused]] and [[nodiscard]] already cover it?
--
 Nevin ":-)" Liber  <mailto:ne...@eviloverlord.com>  +1-847-691-1404

Making it opt-in defeats the point, right? because then existing code would still be hit with lost of warnings, unless the warning would be off by default, was that would you ment?

janwi...@gmail.com

未讀,
2017年10月12日 下午5:55:382017/10/12
收件者:ISO C++ Standard - Future Proposals、gmis...@gmail.com
I think in case of a default-off warning the  [[maybe_unused]] attribute could provide the same information as making it unnamed.

Matthew Woehlke

未讀,
2017年10月12日 下午6:11:212017/10/12
收件者:std-pr...@isocpp.org、janwi...@gmail.com、gmis...@gmail.com
On 2017-10-12 17:46, janwi...@gmail.com wrote:
> What I was suggesting is that by introducing a syntax to explicitly make
> something unnamed, the compiler would then be free to emit warnings for all
> other cases where an object is not referenced after construction, without
> needed to evaluate whether the constructor/destruction has side-effects or
> not.
>
> This is what you wanted right?

Yeeeee...maybe? I seem to recall that defining "not referenced after
construction" was not so simple as it seems.

> On the other hand, I don't really see the value in putting that specific
> warning in the standard itself, but any compiler would be free do to do it
> and it would be easier to implement.

In any case, I don't think the standard would have anything stronger
than a suggestion regarding warnings. (IIRC, there is anyway no such
thing as a "warning" in the standard.) What would be proposed would be
an attribute to annotate types that should not produce such warnings.

IOW, the only actual *standardese* would be that an attribute with
such-and-such name exists.

--
Matthew

Matthew Woehlke

未讀,
2017年10月12日 下午6:19:312017/10/12
收件者:std-pr...@isocpp.org、Nevin Liber、gmis...@gmail.com
On 2017-10-12 17:39, Nevin Liber wrote:
> You want opt-out, which will generate far too many false positives on
> existing, working code. For many businesses, changing existing, working
> code has a very non-trivial cost.

Opt-out by *adding an attribute*. If that's too hard... just turn the
bloody warning off. Geez.

The problem with opt-*in* is that 98% of classes would need to be annotated.

> If it were opt-in, do [[maybe_unused]] and [[nodiscard]] already cover it?

Not really; you'd have to annotate every *use* of a type that it is okay
to keep in scope but not otherwise use. [[nodiscard]] is too broad a
brush, and [[maybe_unused]] is to narrow. Plus [[nodiscard]] is opt-in,
which is wrong per above.

--
Matthew

Matthew Woehlke

未讀,
2017年10月12日 下午6:25:532017/10/12
收件者:std-pr...@isocpp.org、Nevin Liber、gmis...@gmail.com
Point of clarification: the *warning itself* should not necessarily be
on by default. Probably it should not be, initially, until users have
had time to adapt to the idea of using the new attribute, and compilers
have had time to work the kinks out of when to warn.

However, *if* the warning is enabled, the default behavior should be to
warn if a class is "unused" *unless* the class has the attribute saying
that's okay. Because... those are rare; classes which should be "used"
(besides just being constructed and left in scope) are the exception,
not the rule.

--
Matthew

gmis...@gmail.com

未讀,
2017年10月12日 晚上9:48:552017/10/12
收件者:ISO C++ Standard - Future Proposals、ne...@eviloverlord.com、gmis...@gmail.com


On Friday, October 13, 2017 at 11:25:53 AM UTC+13, Matthew Woehlke wrote:
On 2017-10-12 18:19, Matthew Woehlke wrote:
> On 2017-10-12 17:39, Nevin Liber wrote:
>> You want opt-out, which will generate far too many false positives on
>> existing, working code.  For many businesses, changing existing, working
>> code has a very non-trivial cost.
>
> Opt-out by *adding an attribute*. If that's too hard... just turn the
> bloody warning off. Geez.
>
> The problem with opt-*in* is that 98% of classes would need to be annotated.
>
>> If it were opt-in, do [[maybe_unused]] and [[nodiscard]] already cover it?
>
> Not really; you'd have to annotate every *use* of a type that it is okay
> to keep in scope but not otherwise use. [[nodiscard]] is too broad a
> brush, and [[maybe_unused]] is to narrow. Plus [[nodiscard]] is opt-in,
> which is wrong per above.

My suggestion is to use an attribute that says construction only counts as use.
And if you don't use that attribute on your class and then construct an instance of that class but then don't call any members of it, you will get a warning. To disable that warning, use the attribute on the class or construct definition and it will remove the warning for all instances of that class that are constructed but otherwise not used.

I don't mind what the attribute is called as long as it follows the semantics I said.
You only annotate classes where construction only is ok. By default classes that are not annotated should be considered as suspicious (and so yield a warning) if they are constructed but otherwise not used.
I think this is the right semantics because the majority of classes in my opinion will require no annotation. std::string being an example of something that would require no annotation, as by default just doing std::string s; inside a function and not calling any methods on it should count as something you want to be warned about so you can just remove it.

Since I am suggesting that by default, none of this affects code generation, I see why this warning can't be on by default. It would be a little irritating, but I think it will find genuine issues straight away and the cure is easy. Which is the whole point of it.

The standard library would be updated so classes there wouldn't warn. Old compilers don't know about the attributes and don't care so they would not warn. New compilers know about the attributes and also can offer additional compile options to say disable this or ignore certain classes where the user can't update the code base. In any case, since it doesn't affect code generation, I'd really like to see this error on by default. It people really feel it shouldn't be on by default to begin with, I can live with that, but then when will it ever get put on by default. But I think as we can't break any code with this, be brave and make it on by default.

gmis...@gmail.com

未讀,
2017年10月12日 晚上9:56:492017/10/12
收件者:ISO C++ Standard - Future Proposals、gmis...@gmail.com
We can't break any code from this feature, by default it does not affect optimization, so put the warnings on by default is my feeling.
The [[construction_only_is_use]] attribute (or whatever I called it) says this class is ok to be just constructed but never otherwise used.
My attribute means just construction of this class counts as use. So maybe_unused is wrong for that purpose as it's the opposite meaning I think.
[[nodiscard]] might work though. I'm not sure nodiscard is asclear as what I want. But I'm open to it.

I think agree on the semantics of what I'm saying first then worry about the name.

gmis...@gmail.com

未讀,
2017年10月12日 晚上10:00:152017/10/12
收件者:ISO C++ Standard - Future Proposals、gmis...@gmail.com
You want opt-out, which will generate far too many false positives on existing, working code.  For many businesses, changing existing, working code has a very non-trivial cost.

If it were opt-in, do [[maybe_unused]] and [[nodiscard]] already cover it?
--
 Nevin ":-)" Liber  <mailto:ne...@eviloverlord.com>  +1-847-691-1404

My proposal doesn't effect any existing code, in terms of code generation anyway. Everything will work as it did before.
Sure it might generate some diagnostics, but only for classes that have semantics like lock_guard.
I think they will be in the minority and the fix is simply to annotate the class or constructor with an attribute. That's it.
if the warnings are on by default I suspect it will find a reasonable number of unused variables. You'll probably spend as much time fixing them on a large code base as you would annotating the few classes that are genuinely construction only types.

Matthew Woehlke

未讀,
2017年10月13日 上午10:11:072017/10/13
收件者:std-pr...@isocpp.org、gmis...@gmail.com
On 2017-10-12 21:56, gmis...@gmail.com wrote:
> We can't break any code from this feature, by default it does not affect
> optimization, so put the warnings on by default is my feeling.

The reason not to enable the warning by default is that a) it will
result in new warnings in existing code, and b) some people build with
-Werror (and/or the MSVC equivalent). This is what folks are talking
about when they express concern that this would "break" existing code.

However, this all is somewhat beside the point, because it has no impact
on the standard, which does not specify warnings. Ultimately, it is the
vendors that will decide what is best for their customers as to whether
to warn by default or not.

> The [[construction_only_is_use]] attribute (or whatever I called it) says
> this class is ok to be just constructed but never otherwise used.
> My attribute means just construction of this class counts as use. So
> maybe_unused is wrong for that purpose as it's the opposite meaning I think.
> [[nodiscard]] might work though. I'm not sure nodiscard is asclear as what
> I want. But I'm open to it.

The problem with [[nodiscard]] is that it is meant to require "using"
the class... whatever that means. By itself, it is not granular enough
to cover both a class/value that really needs to be *checked*, and the
use case you're targeting (a class that just needs to stay in scope for
a bit).

I'd originally proposed two attributes: one that says "don't just drop
this on the floor", and one that says "you need to do something with
this". However, the more I think about it, that doesn't cover your use
case, which is to treat *every explicitly constructed object* as the
latter. So, actually, I think your proposed attribute is the right approach.

Yours should combine with [[nodiscard]] to say "sticking this in a
variable and keeping it around for a bit is sufficient". Without that,
you implicitly have to "do something" with the object. *Every explicit
instantiation* would implicitly become [[nodiscard]]. Explicit use of
[[nodiscard]] would be relegated to function returns, to annotate
between functions where the result is useful but not critical, and where
ignoring the result is a logic error, with class use viewed as a
convenience for implicitly marking all function uses that return that
type (which is the case today, anyway).

I'm not sure if it's reasonable to argue that [[maybe_unused]], applied
to a type, should have that effect. Mostly because it seems confusing.
However, I could possibly entertain an argument to that effect.

--
Matthew

Jan Wilmans

未讀,
2017年10月13日 上午10:52:472017/10/13
收件者:std-pr...@isocpp.org、gmis...@gmail.com
Fully agree, with a side-note, that making the object unnamed would be identical to marking it with attributes that say "keeping this around for a bit is sufficient", with an added bonus of not _being able_ to do anything else with it.

Matthew Woehlke

未讀,
2017年10月13日 中午12:34:152017/10/13
收件者:std-pr...@isocpp.org、Jan Wilmans、gmis...@gmail.com
On the one hand, I see the utility when the type is a "legacy" type
that's okay if the only "use" is constructing it and keeping it around a
bit. OTOH, if the type is *not* such a critter, you're allowing users to
write garbage like `unnamed std::string{"Hello!"};` with no warning.

I think I'd prefer allowing to mark declarations (anonymous or
otherwise) with the new attribute for cases that the type itself is not
marked, but should have been.

--
Matthew

gmis...@gmail.com

未讀,
2017年10月13日 下午5:12:292017/10/13
收件者:ISO C++ Standard - Future Proposals、gmis...@gmail.com


On Saturday, October 14, 2017 at 3:11:07 AM UTC+13, Matthew Woehlke wrote:
On 2017-10-12 21:56, gmis...@gmail.com wrote:
> We can't break any code from this feature, by default it does not affect
> optimization, so put the warnings on by default is my feeling.

The reason not to enable the warning by default is that a) it will
result in new warnings in existing code, and b) some people build with
-Werror (and/or the MSVC equivalent). This is what folks are talking
about when they express concern that this would "break" existing code.

However, this all is somewhat beside the point, because it has no impact
on the standard, which does not specify warnings. Ultimately, it is the
vendors that will decide what is best for their customers as to whether
to warn by default or not.



If this feature ever sees the light of day then I suspect you will be right about it not being on by default because of the reasons you say but I'll be disappointed if is for these reasons never the less.
I think -Werror is all well and good, but personally, I don't think my suggested diagnostic should obey this flag, not without some addition -WIreallymeanit flag anyway. Because the warning isn't likely to mean any code is broken. It's not meant to affect any code generation at all. It typically means you've left an object in that isn't used like the redundant std::string from my example and that will likely be optimized away anyway.

I would be quite happy that this warning actually be classes as an "informational" message which I think some compilers can issue (so it's neither a warning nor an error) if the idea would appease people to get on by default. I'd be interested what people think about that idea and if they are against on by default. I'm really quite for on by default for this feature. But obviously not at the cost of not getting it at all. It'd be great to have a strong rationale for it being on by default even if vendors ultimately do what they want to do with regard to warnings, I think this is a simple feature though that should ideally have some baseline consistent level of support across compilers.






 
回覆所有人
回覆作者
轉寄
0 則新訊息