If a variable's intended scope is truly local, it would only make sense to me to keep it that way. This is what I have always done. However I recently switched from vim to eclipse at work and eclipse is flagging my constructor if every member variable is not initialized in the constructor. For example, in the code below, it compiles just fine. g++ has no problem with it. Eclipse on the other hand tells me that 'a' should be initialized in the constructor.
Is there any reason why this warning might be relevant or is it just worth ignoring all together?
class C
{
public:
C(){}
~C(){}
void foo();
};
void C::foo()
{
int a;
}
int main() {
C c;
return 0;
}
Eclipse on the other hand tells me that 'a' should be initialized in the constructor.
a cannot be initialized in the constructor because it's a local variable of the member function C::foo(). Eclipse is giving you a bogus warning.
Related
As in the question:
let's say I have a small piece of code like this:
#include <iostream>
using namespace std;
struct foo {
int a;
foo() : a(12) {};
};
int
main()
{
volatile foo x;
return 0;
}
compiled with g++ -g -O2 it turns out, that x initialization is optimized away.
That one however:
#include <iostream>
using namespace std;
struct foo {
volatile int a;
foo() : a(12) {};
};
int
main()
{
volatile foo x;
return 0;
}
calls the constructor.
If I try to use the variables inside the code, (ie. cout << foo.a << endl;) the assembly output is equivalent in both cases.
Do I get the following right, that:
In the first case, there's no access to the struct at all, so it gets optimized away completely.
In the second one, struct's field is indicated as the one possible to change also during the construction and for that reason foo() is called no matter what.
Added:
I've tried fiddling with the above code:
calling things like while(foo.a--); works as expected, it actually happens instead of being deleted/replaced by result during optimization, thus it seems the volatile is actually inherited, yet the ctor behaves in this strange (or at least unexpected at first) way.
EDIT number 2:
I checked it with clang and MSVC and it behaves the same way as in gcc.
My understanding is as follows (and I am not sure about it):
In C++ volatile keyword forces compiler not to optimize seemingly redundant loads and stores to memory, i.e. if you have such example code:
int x = 5;
x = 6;
It will not be changed to:
int x = 6;
This is because x could be pointing to some address in memory, that is read by others, while you don't read it really in your program (imagine that you are sending some configuration over USART to microcontroller by writing to certain memory address, and the microcontroller reads it's configuration from that address - if compiler was to optimize writes to this memory, then whole program would malfunction).
Another thing that one must remember is that when instance of a class is declared with volatile specifier, then its members inherit this specifier (as Igor Tandetnik pointed out in comment, referring to C++ Standard). But this is not the whole truth, because in order to get volatile behaviour, you would have to call member functions, that are marked as volatile - similar to marking member function as const (please see this: http://www.devx.com/tips/Tip/13671). Because AFAIK ctors/dtors cannot be marked with volatile keyword (as in Defining volatile class object), you would have to change your code a bit (perhaps invoking volatile member function from within ctor would do the thing, but this is only a guess).
My code looks like this:
class myClass{
public:
static int a;
};
void myFunc()
{
int myClass::a = 1;
}
I see the following compilation error
error C2655: 'myClass::a' : definition or redeclaration illegal in current scope
I make the following change and everything goes fine. Any idea?
class myClass{
public:
static int a;
};
int myClass::a = 1;
void myFunc()
{
}
Logically think like this:
If you never call myFunc(), myClass::a is not defined. So it must be in global scope.
In your first code snippet, potentially you may use myClass::a even without defining it, so it not allowed and former syntax is not valid C++.
Static variable must be initialized before program start, so if you initialized it in a function, there is chance that it will not be initialized at all. So the compiler should pose this as an error. Static variable is allocated at compile time (before program run). Hope this help.
If you define the static member data in a function, it's linkage is internal to the function. The linkage required for them is global.
Isn't the extern keyword supposed to simply 'blind' the compiler? Here are the codes that i can't understand why it is without an error.
struct A {
int a;
};
class B {
static A x;
public:
void f() { x.a=0; }
};
extern A B::x; // not allocated.
main() {
B z;
z.f();
}
As you already know, the static member should be instantiated manually. However, i added the extern keyword, which means it's not actually allocated. It is very weird that it compiles fine!
There is no such thing as an extern declaration for static member variables! The variable is declared extern anyway based on the definition of the class. gcc warns that you can't explicitly declare a static member variable to be extern. However, both gcc and clang compile and link the code without further ado, clearly ignoring the extern.
Of course, with the above code it is also clear that you are compiling with some non-standard mode in the first place as main() relies on the implicit int rule which was never part of C++.
I got 17 integer constants that I'd like to have as private in my class. Is it really necessary to use initialization list?
I read somewhere that I can assign values to constants in the header file, but it doesn't seem to work. I get this error message:
sorry, unimplemented: non-static data member initializers
Is it really necessary to use initialization list?
In modern (2011-era) C++, no. In older versions of the language, yes.
Your error message is apologising that your compiler doesn't support the new initialisation syntax for non-static members yet. Assuming you're using GCC (since I recognise that error from that compiler), then according to this page you'll need to upgrade to at least version 4.7 for that feature.
Alternatively, since they're private and constant, you might consider moving them out of the class into a local namespace in the class's implementation file. Of course, that will only work if you don't need to access them from any inline member functions.
Finally, if they have the same values for all instances of the class (which is likely, since they are const and you're able initialise them independently of the constructor arguments), you could declare them static. Then they can be initialised in their declaration (although older compilers might only allow that if they have an integer type). However, if they are odr-used (roughly speaking, if you need to take a pointer or reference to them), then they will also need to be defined in exactly one source file.
.h:
class MyClass {
public:
MyClass();
~MyClass();
int doSomething();
private:
const int m_newint = 1;
const int m_dosomething = 2;
};
.cc:
MyClass::MyClass() {}
MyClass::~MyClass() {}
int MyClass::doSomething() {
return m_dosomething;
}
Is valid C++11 code, make sure your compiler is set to -std=c++11 to use the
feature.
Reading code from other posts, I'm seeing something like this.
struct Foo {
Foo() : mem(0) {}
int mem;
};
What does mem(0) {} does in this case, especially regarding the curly brackets? I have never seen this before and have no idea where else I would find out about this. I know that mem(0), would intialize mem to 0, but why the {}?
Thanks.
Since Foo() is the class' constructor, it must have a body, even if the member variable mem is initialized outside of it.
That's why, in your example, the constructor has an empty body:
Foo() : mem(0)
{
// 'mem' is already initialized, but a body is still required.
}
It defines the constructor of the class. The part after the colon is the initialization list, in which the mem member is initialized to zero using a constructor call.
Compare:
int a(0);
int b = 0;
These two do the same, but the former is more in line with how object construction typically looks in C++.
int c++ you can define your method implementation in .h file
class MyClass
{
public:
MyClass(){
.....
}
void doSomething(){
.....
}
~MyClass(){
.....
}
};
Usually it used in templates implementation. Also you could use this method of class declaration in case you would like to avoid libraries linking and you prefer to give to user all your code so he can include your file without linking any lib file to his project.