In CentOS 6.5, I have a class List like:
// list.hpp
namespace foo
{
class List
{
public:
virtual int reserveMem ( int size) = 0;
virtual int Insert ( int val) = 0;
virtual int Find ( int val) = 0;
virtual bool Empty() = 0;
};
}
It's part of the source code of a shared library. And I can build the whole library without any error or warning messages with g++ (version 4.4.7). The compiling flags used are
-g -fPIC -Wall -Wextra -Werror
Then we have another app which just includes a header file which includes this header file and got:
list.hpp:14: error: 'class List' has virtual functions and accessible non-virtual destructor
The warning message is valid. But g++ never complains about it when I build the library. Does anyone know why?
The warning is controlled by the -Wnon-virtual-dtor option, which is not included in -Wall or -Wextra. Presumably you are using different warning options to build the app and the library. Building the app seems to be done with -Wnon-virtual-dtor enabled, or maybe the -Weffc++ option which includes -Wnon-virtual-dtor
I consider that warning to be annoying and unhelpful, the -Wdelete-non-virtual-dtor is much more useful because it only warns if you actually try to delete a foo::List*, and is included in -Wall
Related
I'm trying to figure out something in VCVRack.
In Template.hpp
using namespace rack;
...
struct SlowSliderWidget : public OpaqueWidget {
void draw(NVGcontext *vg) override;
};
then in MyWidget.cpp
#include "Template.hpp"
namespace rack {
void SlowSliderWidget::draw(NVGcontext *vg) {
nvgBeginPath(vg);
nvgRect(vg, 0, 0, 100, 100);
nvgFill(vg);
}
} // namespace rack
This gives me the following compiler error :
g++ -Wsuggest-override -std=c++11 -DSLUG=Template -fPIC -I../../include -I../../dep/include -DVERSION=0.6.0 -MMD -MP -g -O3 -march=nocona -ffast-math -fno-finite-math-only -Wall -Wextra -Wno-unused-parameter -DARCH_LIN -c -o build/src/MyWidget.cpp.o src/MyWidget.cpp
src/MyWidget.cpp:6:43: error: definition of ‘void SlowSliderWidget::draw(NVGcontext*)’ is not in namespace enclosing ‘SlowSliderWidget’ [-fpermissive]
void SlowSliderWidget::draw(NVGcontext *vg) {
^
../../compile.mk:64: recipe for target 'build/src/MyWidget.cpp.o' failed
Now, searching around I find various complaints about this type of error in GCC.
But all of them seem to be about attempts to redefine the meaning of the same class name in the same namespace.
But if I understand my C++ here, I am NOT trying to redefine the name. I declare the name SlowSliderWidget and the SlowSliderWidget::draw in the Template.hpp file and I simply try to define the function body of draw in the MyWidget.cpp file.
So why am I getting an error message? The wording seems to imply I'm not in the same namespace. But in both files I am in namespace rack. Aren't I?
i was just making a few changes to my program, when all of a sudden g++ complained with an internal compiler error.
Clang however compiles it without any problems and also does not give any warnings, that would indicate anything weird.
I distilled the problem down to this:
#include <functional>
template<typename T>
class A{
T someVar;
};
template<typename T>
class B {
int x;
std::function<A<double>(A<int>&)> someLambda = [&](A<int>& aInt){
int xVar = x;
A<double> aRet;
return aRet;
};
};
int main(int argc, char** argv){
B<int> a;
return 0;
}
I tried both GCC 4.9.2 and 4.8.4, with both failing (internal compiler error).
Flags I used:
g++ -std=c++11 -O0 -g -Wall main.cpp -o gccBin
clang++ -std=c++11 -O0 -g -Wall main.cpp -o clangBin
main.cpp: In instantiation of 'struct B<int>::<lambda(class A<int>&)>':
main.cpp:10:7: required from here
main.cpp:14:24: internal compiler error: in tsubst_copy, at cp/pt.c:12569
int xVar = x;
^
libbacktrace could not find executable to open
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
Clang++(3.5.1) compiles it without a problem, as I mentioned.
I also tried multiple machines, everywhere the same.
Is there some kind of error I overlooked? I searched a bit on the internet and the only similar problems i could find should have been fixed by now (as the bugtracker states).
Could maybe someone try and run this code on their machine or give other advice?
Thank you,
Lazarus
It's a compiler bug. Just go ahead and file a bug report to the GCC dudes!
g++ generates warnings for unused local variables. Is it possible to have g++ warn for unused class member variables and/or global variables?
class Obj {
public:
Obj(int a, int b) : num1(a), num2(b) {}
int addA(int i) {
return i + num1;
}
private:
int num1;
int num2;
};
How do I get g++ to warn me that num2 is unused?
UPDATE:
I am currently compiling with:
g++ -Wall -Wextra -pedantic *.cc -o myprogram
Clang's -Wunused-private-field enables the warning you're asking for. On your code base, it shows:
$ clang -Wunused-private-field /tmp/nic.cpp
/tmp/nic.cpp:10:22: warning: private field 'num2' is not used [-Wunused-private-field]
int num2;
^
1 warning generated.
I'm not aware of any such warning. Additionally I'll speculate that the reason it doesn't exist is because it can't be reliably generated in all cases, so they elected to not spend effort making it work for some subset of cases. For example, if the class friends another function that's in a library, the compiler would have no way of knowing if that library mutated any particular class attribute or not.
You can use cppcheck (download). cppcheck --enable=style does exactly what you need, among other useful things.
I am trying to create a baremetal c++ application for a cortex-M4 device. My toolchain is ARM-GCC
I have noticed that the code size has shot up by 300kb which is 30% of the available flash size. There is a whole truckload of stuff from the standard libraries that gets linked in bloating TEXT, DATA and BSS areas.
Can this be reduced?
The application is the venerable blinky program with a :
- Blinky.c containing the C routine to toggle a port pin in a while loop
- Main.cpp containing the main() and a simple class with a constructor
- Device startup file which does program loading and yields control to main()
The c file is compiled using gcc while the cpp is compiled using g++. The linker is invoked via g++ to automatically link in stdlibc++(with the assumption that only necessary object fies from the stdlibc++ will be linked in).
I even have -fno-rtti and -fno-exceptions as compile options to g++, but the savings are a pittiance.
By the way, the generated binary works file.
This is the Main.cpp
#include <iostream>
using namespace std;
extern "C" void Toggle_Pin(uint8_t Speed);
void *__dso_handle = (void *)NULL;
void __cxa_atexit(void (*Arg)(void *), void *Arg2, void *Arg3){}
void __cxa_guard_acquire(void){}
void __cxa_guard_release(void){}
void __aeabi_atexit(void (*Arg)(void *), void *Arg2, void *Arg3){}
class Computer
{
public:
uint32_t aa;
uint32_t bb;
Computer();
};
Computer::Computer()
{
aa=0;
bb=0;
for(uint8_t i=0;i < 10; i++)
{
Toggle_Pin((uint8_t)100);
}
}
Computer a;
int main(void)
{
a.aa = 10;
Toggle_Pin();
}
And these are my compilation options provided to g++.
-O0 -ffunction-sections -Wall -fno-rtti -fno-exceptions -mfloat-abi=softfp -Wa,-adhlns="$#.lst" -c -fmessage-length=0 -mfpu=fpv4-sp-d16 -MMD -MP -MF"$(#:%.o=%.d)" -MT"$(#:%.o=%.d) $#" -mcpu=cortex-m4 -mthumb -g3 -gdwarf-2 -o "$#" "$<"
Linker options provided to g++:
-T LinkerScript.ld" -nostartfiles -L"Path to libraries" -Wl,-Map,"Project.map" -mcpu=cortex-m4 -mthumb -g3 -gdwarf-2 -o "Project.elf" "#makefile.rsp" $(USER_OBJS) $(LIBS)
Remove part with
#include <iostream>
using namespace std;
you don't need it. I guess it adds extra global objects / variables and might leave some definitions in binary.
Also use -Os
-Os
Optimize for size. -Os enables all -O2 optimizations that do not typically increase code size. It also performs further optimizations designed to reduce code size.
Suppose we have the following code:
#if !defined(__cplusplus)
# error This file should be compiled as C++
#endif
#include <stdio.h>
#include <string>
//#define USE_CXX_CLASS
#ifdef USE_CXX_CLASS
class SomeClass
{
public:
SomeClass() {}
~SomeClass() {}
std::string GetSomeString()
{
// case #1
}
};
#endif // USE_CXX_CLASS
int foo()
{
// case #2
}
int
main (int argc, char *argv[])
{
(void)argc;
(void)argv;
#ifdef USE_CXX_CLASS
SomeClass someInstance;
someInstance.GetSomeString();
#endif // USE_CXX_CLASS
foo();
return 0;
}
And suppose that it were to be compiled the C++ compiler (and not the C compiler) from GCC version 4.2.1 with the options -Wreturn-type -Werror=return-type. If the above code is compiled as is without first uncommenting the //#define USE_CXX_CLASS line above, then you will see a warning but no error:
.../gcc-4.2.1/bin/g++ -g -fPIC -Wreturn-type -Werror=return-type test.cpp -c -o test.o
test.cpp: In function 'int foo()':
test.cpp:26: warning: control reaches end of non-void function
But if the //#define USE_CXX_CLASS line is uncommented, then the warning is treated as an error:
.../gcc-4.2.1/bin/g++ -g -fPIC -Wreturn-type -Werror=return-type test.cpp -c -o test.o
test.cpp: In member function 'std::string SomeClass::GetSomeString()':
test.cpp:18: error: no return statement in function returning non-void [-Wreturn-type]
gmake: *** [test.o] Error 1
Yes, one is a non-member function (case #2), and the other is a C++ function (case #1). IMO, that should not matter. I want both conditions treated as an error, and I don't want to add -Werror or -Wall at this point in time (probably will do so later, but that is out of scope of this question).
My sub-questions are:
Is there some GCC switch that I am missing that should work? (No I do not want to use #pragma's.)
Is this a bug that has been addressed in a more recent version of GCC?
For reference, I have already poured through other similar questions already, including the following:
Why does flowing off the end of a non-void function without returning a value not produce a compiler error?
C question: no warning?
Is a return statement mandatory for C++ functions that do not return void?
It has been fixed, it works well with g++ 9.3: both member functions and free functions are treated as error with -Wall -Werror=return-type
I do see an error even w/o the USE_CXX_CLASS flag. i.e. g++ is consistent with the error for both class member functions and non member functions.
g++ (GCC) 4.4.3 20100127 (Red Hat 4.4.3-4)
It seems to me that what you need is a shell script wrapper around gcc.
Name it something like gcc-wrapper and g++-wrapper.
In your Makefile set CC and CXX to the wrappers.
Have the wrapper invoke GCC and pipe its output to another program which will search for your desired warning strings.
Have the search program exit with an error when it finds the warning.