[Bug c++/52103] need a finer control over -Woverloaded-virtual
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52103 --- Comment #3 from mlg 2012-02-04 09:50:39 UTC --- > You can use C++11 explicit override control Since it is a lot of existing code, I'm afraid I'd have to have _them_ used override 5 or 10 or so years ago.
[Bug c++/52103] need a finer control over -Woverloaded-virtual
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52103 --- Comment #1 from mlg 2012-02-03 09:14:36 UTC --- $ g++ --version g++ (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2 Copyright (C) 2010 Free Software Foundation, Inc. [...]
[Bug c++/52103] New: need a finer control over -Woverloaded-virtual
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52103 Bug #: 52103 Summary: need a finer control over -Woverloaded-virtual Classification: Unclassified Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: m...@yandex.ru Let me first explain my use case. I have a large existing non-gcc source which I am porting to a platform supported by gcc. Due to the difference in dialects, I have to insert const modifiers for the function parameters. But when I change the signature of a base class by inserting const, it does not affect the derived classes -- instead, it just breaks inheritance. This is where -Woverloaded-virtual comes to play. Unfortunately, it generates too much noise, rendering the feature almost unusable for this case. Indeed, the best place to hide an important message is a hundred of useless messages of the same sort. (So this is a usability issue.) Considering that -Woverloaded-virtual is rather doing what its name suggests, I propose to implement two finer-tuned options. -Woverloaded-modifiers gives a warning when the two signatures differ only in modifiers like const. (Consider also volatile and restrict.) struct Base{ void f(Base& x){} }; struct Derived: public Base{ void f(const Base& x){} }; -Woverloaded-compatible gives a warning when the two signatures differ in parameter classes, but one of the classes is a descendant of the other. struct First{ void g(Base&x){} }; struct Second{ void g(Derived&x){} }; I underline that -Woverloaded-modifiers and -Woverloaded-compatible should not be limited to virtual functions: virtual could be implied if the function is virtual in the base class. (You may disagree with me here, in this case I want to hear your arguments.) (I do not insist on namely these names, maybe you have some better suggestion(s), but I insist on the functionality.) As to -Woverloaded-virtual, I think, it should be left as it is. Now some code example. Note that with -Woverloaded-modifiers -Woverloaded-compatible there should be no warning for struct ThereIsNoProblem because the argument types are unrelated. $cat inher4.cpp #include struct Base{ void f(const Base& x){printf("Base.f()\n");} }; struct Derived: public Base{ void f(Base& x){printf("Derived.f()\n");} }; struct First{ virtual void g(Base&x){printf("First.g()\n");} }; struct Second:public First{ virtual void g(Derived&x){printf("Second.g()\n");} }; struct ThereIsNoProblem:public First{ virtual void g(int x){printf("ShouldBeValid.g()");} }; int main() { Base x; Derived y; Base*py=&y; y.f(x); py->f(Base()); Second z; First*pz=&z; //z.g(x); // error: no matching function for call to ‘Second::g(Base&)’ z.g(y); pz->g(x); pz->g(y); } $g++ -Woverloaded-virtual inher4.cpp inher4.cpp:6:28: warning: ‘virtual void First::g(Base&)’ was hidden inher4.cpp:7:42: warning: by ‘virtual void Second::g(Derived&)’ inher4.cpp:6:28: warning: ‘virtual void First::g(Base&)’ was hidden inher4.cpp:8:52: warning: by ‘virtual void ThereIsNoProblem::g(int)’ $./a.out Derived.f() Base.f() Second.g() First.g() First.g() $
[Bug c++/47940] warn about calls to a pure virtual from a constructor/destructor
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47940 --- Comment #6 from mlg 2011-03-01 17:23:41 UTC --- (In reply to comment #4) > (In reply to comment #0) > > > > Functions that call pure virtual functions cannot > > be called from constructors and destructors. > > This may be discovered at compile-time, and the above > > text makes a good error/warning message. > > I'm not sure it makes a good diagnostic, consider: > > struct abc { > abc(bool nasal_demons) { if (nasal_demons) fly(); } > void fly() { doFly(); } > virtual void doFly() = 0; > }; > That is the most dangerous situation: the crashing call is buried [deep] in the control flow. The deeper it is buried, the more valuable a warning/error message would be. Ok, "a pure virtual function may be called indirectly from a constructor/destructor" > Ideally the diagnostic for this would say "may call a pure virtual" for cases > where it can't be determined. Probably you are right, a kind of "I know what I'm doing" pragma would be useful as well. I also want to note that the top-level function may be virtual: [NOTE: usefunc() is virtual here] ==byebug2.cpp== #include class Base { public: ~Base() { usefunc(); } virtual void func()=0; virtual void usefunc() { func(); } }; class Derived: public Base { public: virtual void func() {} }; int main() { Derived d; printf("life is good\n"); return 0; } ==eof== $ g++ -Wall -Wextra byebug2.cpp $ ./a.out life is good pure virtual method called terminate called without an active exception Aborted
[Bug c++/47940] can call a pure virtual from a constructor/destructor
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47940 --- Comment #2 from mlg 2011-03-01 11:34:30 UTC --- Yes it _is_ hard to detect. My colleague was suspecting a build system bug/feature at first (hours for a full rebuild). If it was a direct call, there would be a linker error. >If the call was direct to func instead, >it would be better. Unfortunately or fortunately, refactoring a huge real world application to make bugs easier for the compiler to detect is not an option.
[Bug c++/47940] New: can call a pure virtual from a constructor/destructor
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47940 Summary: can call a pure virtual from a constructor/destructor Product: gcc Version: 4.4.5 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: m...@yandex.ru A colleague of mine have been examining a crash that boils down to the following: --hellobug.cpp-- class Base { public: Base() { usefunc(); } virtual void func()=0; void usefunc() { func(); } }; class Derived: public Base { public: virtual void func() {} }; int main() { Derived d; return 0; } --eof-- $ g++ -Wall -Wextra hellobug.cpp {just nothing} $ ./a.out pure virtual method called terminate called without an active exception Aborted That is, "you asked for it, you got it" [1]. == [1] from "Real Programmers Don't" == A variation: ==byebug.cpp== #include class Base { public: ~Base() { usefunc(); } virtual void func()=0; void usefunc() { func(); } }; class Derived: public Base { public: virtual void func() {} }; int main() { Derived d; printf("life is good\n"); return 0; } ==eof== $ g++ -Wall -Wextra byebug.cpp {again nothing} $ ./a.out life is good pure virtual method called terminate called without an active exception Aborted I have to note that in a big software project, the mistake is not so obvious. But what can be done? Functions that call pure virtual functions cannot be called from constructors and destructors. This may be discovered at compile-time, and the above text makes a good error/warning message. WHAT I GET: no warning WHAT I WOULD EXPECT: a warning or an error message: "Functions that call pure virtual functions cannot be called from constructors and destructors" $ gcc -v Using built-in specs. Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.4.4-14ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.4 --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5)
[Bug preprocessor/38179] need a warning: macro parameter is not a whole expression within macro body
--- Comment #2 from mlg7 at yandex dot ru 2008-11-21 08:44 --- (In reply to comment #1) > The expanded text for the first one is: > int t = 1|2 & 0xFF00 ? dothis(1|2) : dothat(1|2); > > Maybe I am missing something here. > the human who is writing int t = MYMACRO(FLAGA|FLAGB); obviously means int t = (1|2) & 0xFF00 ? dothis(1|2) : dothat(1|2); // #1 while the compiler treats this as int t = 1|(2 & 0xFF00) ? dothis(1|2) : dothat(1|2); // #2 (google for "C Operator Precedence" if you need to check it) This is a well-known preprocessor gotcha. I propose to add a warning for such cases. PS That is, there are two gotchas: the problem with expressions as macro parameters and the same problem with expressions in generated text. The Clever Books tell folks to enclose all macro parameters in parens and enclose the whole macro body in parens. So, the recommended way for writing #define MYMACRO(x) x & 0xFF00 ? dothis(x) : dothat(x) is #define MYMACRO(x) ((x) & 0xFF00 ? dothis((x)) : dothat((x))) It looks like LISP but it works. But practice shows that not everybody reads The Clever Books... -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38179
[Bug c/38179] New: need a warning: macro parameter is not a whole expression within macro body
This affects both C and C++ (and probably Objective C that I never used) (In fact, I propose two warnings: 1. macro parameter is not a whole expression within macro body 2. expanded macro body is not a whole expression within macro use context ) I propose to add a warning (and include it in -Wall) for the following sort of bugs: #define FLAGA 1 #define FLAGB 2 #define MYMACRO(x) x & 0xFF00 ? dothis(x) : dothat(x) int t = MYMACRO(FLAGA|FLAGB); The expanded text is int t = FLAGA|FLAGB & 0xFF00 ? dothis(FLAGA|FLAGB) : dothat(FLAGA|FLAGB); and it is obvious that due to the bug the conditional expression is evaluated to true while it should have been false, and the right branch will not be chosen. (this would produce the "macro parameter is not a whole expression within macro body" warning) The same applies to int t = 10 + MYMACRO(FLAGA|FLAGB); where 10 will be a part of the conditional expression. (this would produce the "expanded macro body is not a whole expression within macro use context" warning) But: it is important not to produce such warnings when the macro parameter or body in principle cannot be a whole expression, for example, contains ";" or "{". - AN APPROACH TO IMPLEMENTATION I would suggest something like "weak parens", say, #( and #) int t = MYMACRO(FLAGA|FLAGB); would expand to int t = #( FLAGA|FLAGB #) & 0xFF00 ? dothis( #( FLAGA|FLAGB #) ) : dothat( #( FLAGA|FLAGB #) ); Here we can issue a warning because when we compare the tree parsed as "weak parens as parens" vs the tree parsed as "weak parens are spaces", we get different results. Surrounding the whole expression with weak parens #{ and #} would solve the problem of expanded macro text broken by higher-priority operators: int t = 10 + MYMACRO(FLAGA|FLAGB); would expand to int t = 10 + #{ #( FLAGA|FLAGB #) & 0xFF00 ? dothis( #( FLAGA|FLAGB #) ) : dothat( #( FLAGA|FLAGB #) ) #} ; and, again, replacing #{ #} with parens or spaces we get different trees. And what about #define OH_MY_GOD 20; y= x = OH_MY_GOD 10; ? It expands to x = #{ 20; y = #} 10; We must just ignore weak parens that are not balanced (both #{ #} and #( #) ). At least, options enabled via -Wall and -Wextra *MUST_NOT* produce warnings for such cases. The same about SOME_MACRO(x();y(), z();t()), weak parens cannot be replaced by parens here. I do not think that checking possible replacement of weak parens by braces { } is that important, we can live without it. Example of a case that is not so important: #define SOME_MACRO(x,y)if(my_boolean)x;else y; SOME_MACRO(x();y(), z();t()) -- Summary: need a warning: macro parameter is not a whole expression within macro body Product: gcc Version: 4.3.3 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: mlg7 at yandex dot ru http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38179
[Bug c++/38053] New: add a warning for b/c*d
If the compiler generates a warning for x&&y||z, it should also generate a warning for a*b/c*d. The problem is that the programmer probably meant a*b/(c*d), that is, a*b/c/d. This relates to both C and C++. -- Summary: add a warning for b/c*d Product: gcc Version: 4.3.3 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: mlg7 at yandex dot ru http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38053