Modify

Ticket #9378 (closed Bugs: wontfix)

Opened 3 years ago

Last modified 11 months ago

g++ 4.7 -Wshadow warnings need attention

Reported by: Tom Browder <tom.browder@…> Owned by: eric_niebler
Milestone: To Be Determined Component: xpressive
Version: Boost 1.55.0 Severity: Problem
Keywords: Cc:

Description

Following are warnings from g++ 4.7

boost/xpressive/detail/core/matcher/assert_word_matcher.hpp:94:11: warning: declaration of 'word' shadows a member of 'this' [-Wshadow]

boost/xpressive/detail/core/sub_match_vector.hpp:151:10: warning: declaration of 'size' shadows a member of 'this' [-Wshadow]

boost/xpressive/detail/core/sub_match_vector.hpp:152:5: warning: declaration of 'size' shadows a member of 'this' [-Wshadow]

boost/xpressive/detail/core/sub_match_vector.hpp:158:5: warning: declaration of 'size' shadows a member of 'this' [-Wshadow]

boost/xpressive/detail/dynamic/sequence.hpp:42:7: warning: declaration of 'xpr' shadows a member of 'this' [-Wshadow]

boost/xpressive/detail/dynamic/sequence.hpp:54:7: warning: declaration of 'xpr' shadows a member of 'this' [-Wshadow]

boost/xpressive/detail/static/transforms/as_set.hpp:161:9: warning: declaration of 'set_' shadows a member of 'this' [-Wshadow]

boost/xpressive/detail/static/visitor.hpp:111:18: warning: declaration of 'self' shadows a member of 'this' [-Wshadow]

boost/xpressive/detail/static/visitor.hpp:30:18: warning: declaration of 'self' shadows a member of 'this' [-Wshadow]

boost/xpressive/detail/static/visitor.hpp:31:11: warning: declaration of 'self' shadows a member of 'this' [-Wshadow]

boost/xpressive/detail/utility/chset/range_run.ipp:107:20: warning: declaration of 'begin' shadows a member of 'this' [-Wshadow]

boost/xpressive/detail/utility/chset/range_run.ipp:108:20: warning: declaration of 'end' shadows a member of 'this' [-Wshadow]

boost/xpressive/detail/utility/hash_peek_bitset.hpp:53:10: warning: declaration of 'icase' shadows a member of 'this' [-Wshadow]

boost/xpressive/detail/utility/hash_peek_bitset.hpp:54:5: warning: declaration of 'icase' shadows a member of 'this' [-Wshadow]

boost/xpressive/detail/utility/hash_peek_bitset.hpp:64:5: warning: declaration of 'icase' shadows a member of 'this' [-Wshadow]

boost/xpressive/detail/utility/hash_peek_bitset.hpp:114:5: warning: declaration of 'icase' shadows a member of 'this' [-Wshadow]

boost/xpressive/detail/utility/hash_peek_bitset.hpp:150:10: warning: declaration of 'icase' shadows a member of 'this' [-Wshadow]

boost/xpressive/detail/utility/hash_peek_bitset.hpp:151:5: warning: declaration of 'icase' shadows a member of 'this' [-Wshadow]

boost/xpressive/detail/utility/hash_peek_bitset.hpp:152:21: warning: declaration of 'count' shadows a member of 'this' [-Wshadow]

boost/xpressive/detail/utility/hash_peek_bitset.hpp:152:47: warning: declaration of 'count' shadows a member of 'this' [-Wshadow]

boost/xpressive/detail/utility/sequence_stack.hpp:68:9: warning: declaration of 'size' shadows a member of 'this' [-Wshadow]

boost/xpressive/detail/utility/sequence_stack.hpp:69:11: warning: declaration of 'size' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:416:25: warning: declaration of 'size' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:689:5: warning: declaration of 'regex_id' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:695:13: warning: declaration of 'begin' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:696:13: warning: declaration of 'end' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:716:10: warning: declaration of 'regex_id' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:716:10: warning: declaration of 'size' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:724:5: warning: declaration of 'regex_id' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:724:5: warning: declaration of 'size' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:745:10: warning: declaration of 'begin' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:745:10: warning: declaration of 'end' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:746:5: warning: declaration of 'begin' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:746:5: warning: declaration of 'end' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:852:5: warning: declaration of 'format' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:854:46: warning: declaration of 'end' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:886:5: warning: declaration of 'format' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:904:5: warning: declaration of 'format' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:922:5: warning: declaration of 'format' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:940:5: warning: declaration of 'format' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:951:5: warning: declaration of 'end' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:973:5: warning: declaration of 'end' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:1000:5: warning: declaration of 'end' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:1035:5: warning: declaration of 'end' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:1047:5: warning: declaration of 'end' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:1124:5: warning: declaration of 'end' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:1174:5: warning: declaration of 'end' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:1315:5: warning: declaration of 'end' shadows a member of 'this' [-Wshadow]

boost/xpressive/match_results.hpp:1319:25: warning: declaration of 'begin' shadows a member of 'this' [-Wshadow]

boost/xpressive/regex_error.hpp:57:7: warning: declaration of 'code' shadows a member of 'this' [-Wshadow]

boost/xpressive/sub_match.hpp:82:5: warning: declaration of 'first' shadows a member of 'this' [-Wshadow]

boost/xpressive/sub_match.hpp:82:5: warning: declaration of 'second' shadows a member of 'this' [-Wshadow]

boost/xpressive/sub_match.hpp:117:5: warning: declaration of 'str' shadows a member of 'this' [-Wshadow]

boost/xpressive/traits/cpp_regex_traits.hpp:520:25: warning: declaration of 'char_class' shadows a member of 'this' [-Wshadow]

boost/xpressive/traits/cpp_regex_traits.hpp:520:77: warning: declaration of 'char_class' shadows a member of 'this' [-Wshadow]

Attachments

Change History

comment:1 Changed 3 years ago by eric_niebler

I appreciate the report. Are any of these actual bugs? That is, is there incorrect code? If not, I'm unlikely to fix these. If you wanted to attach a patch though, I'd be willing to apply it.

comment:2 Changed 3 years ago by Tom Browder <tom.browder@…>

Well ii's hard to say if there is a bug in some cases because the intent of the shadowed variable is not always clear to a user. Is there some reason you use shadow variables?

comment:3 Changed 3 years ago by eric_niebler

I don't "use shadow variables." I use standard C++, or I try to. Is any of my code non-conforming?

comment:4 Changed 3 years ago by mloskot

From #9374

This is a standard C++ idiom and does not make sense to change.

... in some places, of course.

comment:5 follow-ups: ↓ 6 ↓ 7 Changed 3 years ago by rmann@…

I'm not sure I agree it's "standard idiom." Just because it's legal code doesn't mean it's a good idea. It opens you up to subtle programming bugs that can be difficult to spot. We recently found a problem due to shadowing a variable, and so turned on -Wshadow. Now we get hundreds of warnings from Boost (and others) about shadowed variables, making it very difficult to spot our own (potential) errors.

Much better programming style to avoid shadowing all together.

comment:6 in reply to: ↑ 5 Changed 3 years ago by steven_watanabe

Replying to rmann@…:

Much better programming style to avoid shadowing all together.

I very much disagree. It's completely impractical for us to write code that works around all the quirks of the warnings generated by any compiler with any set of options. I personally find this warning much more annoying than useful.

comment:7 in reply to: ↑ 5 Changed 3 years ago by steven_watanabe

Replying to rmann@…:

Now we get hundreds of warnings from Boost (and others) about shadowed variables, making it very difficult to spot our own (potential) errors.

-isystem is your friend if you don't want to see warnings in other folks headers.

comment:8 follow-up: ↓ 9 Changed 3 years ago by anonymous

Not sure how you can think that way. This is not a question of "working around the quirks" of compilers, it's about writing good code. As I said, we had an error due to shadowing. Compilers almost universally support warning you about this, because it leads to mistakes. But code that prevents us from taking advantage of the compiler makes it harder for us to write good code.

Boost itself can benefit from not shadowing variables, so I don't understand why you wouldn't be all for it. It's simple: shadowing variables opens you up to potential errors, and not shadowing is trivial.

comment:9 in reply to: ↑ 8 Changed 3 years ago by steven_watanabe

Replying to anonymous:

But code that prevents us from taking advantage of the compiler makes it harder for us to write good code.

I have no objection to you using this warning for your own code. I almost always end up creating a pair of headers disable_warnings.hpp and enable_warnings.hpp that I use to wrap all the code in a library.

Boost itself can benefit from not shadowing variables,

This is highly doubtful. I've seen too many cases where "fixing" one warning only created a different warning (possibly with another compiler) or worse, introduced a bug because someone was blindly following the compiler's suggestions without fully understanding the consequences of each change. There's really no such thing as a trivial change, and considering the effort required, the chances of introducing new problems, and the likelihood of finding a real bug, I simply don't consider it worthwhile to make these changes in a large existing code base.

comment:10 follow-up: ↓ 11 Changed 3 years ago by rmann@…

Clearly a difference in attitude. A similar bug I wrote against Eigen got a response today that they expect to be shadow-free in their next dot release.

I'm only talking about shadowing, not every possible warning under the sun (although I believe it's generally best to avoid them). Obviously it should be fixed by someone who knows what they're doing, but in this case it should be mechanical (identifying errors, of course, is not. But fixing them such that the code remains equivalent is).

Of course Boost can benefit. Right now, you have no idea if you are inadvertently referencing the wrong variable. If you once forget to properly scope the access to a shadowed variable, you've got a bug. Variables of different name make that more obvious. My personal approach is to modify the name of variables according to their scope (constant, global, static, member, parameter, method-local). Not only does this avoid shadowing (in almost every case you might want to use it; the compiler can catch the rest), it also makes it easy to identify where variables come from, without otherwise redundant use of "this".

disable_warnings.hpp and enable_warnings.hpp is a pretty hacky fix.

comment:11 in reply to: ↑ 10 Changed 3 years ago by steven_watanabe

Replying to rmann@…:

Obviously it should be fixed by someone who knows what they're doing, but in this case it should be mechanical (identifying errors, of course, is not. But fixing them such that the code remains equivalent is).

Mechanically rewriting the code like this has no benefit to anyone.

Either

  1. It's immediately obvious where each variable comes from, or
  2. It isn't obvious what a name refers to.

If (a) is true, then rewriting the code will not make the code more understandable and in fact using mangled names can make it harder to follow. Otherwise, the more (b) is true, the more likely it is that these mechanical changes will accidentally change the behavior.

Besides which, if all you want to do is tell the compiler to shut up, the safest and most reliable solution is to do exactly that, i.e., #pragma GCC warning ignored -Wshadow.

Of course Boost can benefit. Right now, you have no idea if you are inadvertently referencing the wrong variable.

I beg to differ. I'm not.

disable_warnings.hpp and enable_warnings.hpp is a pretty hacky fix.

I don't see why. It means that library code can be compiled with the warning settings that the library author considers useful, rather than whatever each user wants. Suppressing warnings is often necessary anyway (e.g. C4512: Assignment operator could not be generated.) and these headers are a lot more convenient than writing #ifdefs everywhere.

comment:12 Changed 3 years ago by rmann@…

I mean you don't need any special knowledge of what the code is doing to go through and modify variable names to avoid shadowing, if you understand how the compiler resolves scope. Sure, looking at the code, it's obvious which variable is being referenced. What's not obvious is if that was the intent of the programmer of that code.

Why do you think the warning exists at all? if there is no danger to shadowing variables, why does any compiler anywhere support warning you?

The answer is that there IS a danger in doing so. Explicit naming, on the other hand, reduces the likelihood that one will accidentally reference the wrong variable, since the NAME is different. You won't be thinking "foo" when what you really meant was "mFoo" (or "foo_" or whatever style you choose).

Turning off the warning, by any means is sticking your head in the sand and hoping there's nothing wrong. The headers are hacky because you have to litter your code with them. They're a bandaid on the real problem, which is code full of warnings.

If you want to shadow variables in your own code, that's one thing. But code that's used by thousands of others should be free of warnings in the bulk of the compilers it supports.

I clearly can't convince you of the benefit of having warning-free code, shadow or otherwise. It certainly reduces my confidence in Boost being a robust product.

comment:13 Changed 3 years ago by anonymous

I meant to add, of course it benefits everyone. It helps reduce possible mistakes, and it makes it easier to rely on the compiler to catch potential errors.

comment:14 Changed 3 years ago by steven_watanabe

Warnings are not a problem in themselves. They are simply the compiler's best attempt to guess where there are problems. Not all warnings are appropriate for all coding styles. Some warnings are usually useful, some are useful to some people, and some are almost never useful. I'll point out that -Wshadow is not included in -Wall or even -Wextra. I'll also say that I have fixed -Wshadow warnings in the past. My experience was that it was extremely tedious and found no bugs whatsoever. I also had to hack the documentation toolchain to prevent doxygen from showing the ugly mangled names. I don't consider -Wshadow to be much more useful than if the compiler picked a random line of code and said, "warning: there is code on this line. There might be a bug here." I use warning suppression headers because I only have a finite amount of time available and I'd rather spend it doing something productive (like improving the test suite) than spend it looking at hundreds of messages that only have an infinitesimal chance of being a real problem.

I am not the maintainer of xpressive, of course. How this is handled is ultimately Eric's decision.

comment:15 Changed 3 years ago by eric_niebler

  • Status changed from new to closed
  • Resolution set to wontfix

I've already made my feelings known. This is not a priority. Closing "won't fix". I'm happy to fix genuine bugs. I'm not spending my time playing whack-a-mole with compiler warnings.

comment:16 Changed 2 years ago by anonymous

I found this thread when trying to solve my many warnings issued by the inclusion of boost in my code.

I strongly disagree with, or even appalled by Steven's and Eric's comments. Reusing the same name for another variable is just asking for problems - even if you change the scope to a deeper level. It also makes the code harder to debug and understand.

comment:16 Changed 2 years ago by anonymous

I found this thread when trying to solve my many warnings issued by the inclusion of boost in my code.

I strongly disagree with, or even appalled by Steven's and Eric's comments. Reusing the same name for another variable is just asking for problems - even if you change the scope to a deeper level. It also makes the code harder to debug and understand.

comment:17 follow-up: ↓ 18 Changed 2 years ago by eric_niebler

Appalled! I find it remarkable that someone who feels so strongly about such a trivial thing feels it's better to complain to the author in a public forum than to prepare a patch.

comment:18 in reply to: ↑ 17 Changed 11 months ago by anonymous

Replying to eric_niebler:

Appalled! I find it remarkable that someone who feels so strongly about such a trivial thing feels it's better to complain to the author in a public forum than to prepare a patch.

Are you saying if I create a patch, you are going to actually fix it? If yes, I am going to do it.

View

Add a comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
The resolution will be deleted. Next status will be 'reopened'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.