Actually the segmentation fault happens in another program I tried to compile which happens because of this behaviour.
My question is:
This is a bug or my fault?
Reproducible in any way (even if the something
field is private or protected) and here is my example:
main.cc:
#include <iostream>
class Test {
public:
const char* something = "SOMETHING HERE!!!";
Test(const int& number) : Test(something, number) { }
// XXX: changed `something` to `_something` to make it different
Test(const char* _something, const int& number) {
std::cout << _something << std::endl;
std::cout << number << std::endl; }
~Test() { }
};
int main(int argc, char* argv[]) {
Test te1(345);
Test te2("asdasdad", 34523);
return 0;
}
And here is what happens when compiling with:
g++ main.cc -Os -o main
and running with:
./main
the output is:
pi@pi:~/ $ ./main
A"�~ <-- this is random
345
asdasdad
34523
But when I enable optimization with -O0
or -O1
or -O2
... the output is only a new line:
pi@pi:~/ $ ./main
pi@pi:~/ $
G++ version:
pi@pi:~/ $ g++ --version
g++ (Raspbian 6.3.0-18+rpi1) 6.3.0 20170516
const char* something = "SOMETHING HERE!!!";
The default-initializer on the right is, as its name implies, only used when you don't provide an explicit initializer in a constructor's initializer list. Let's look at yours:
Test(const int& number) : Test(something, number) { }
Okay, we're delegating to another constructor. That other constructor will perform full initialization, so the default initializer is not used. But... we're passing in the uninitialized value of something
as parameter.
Test(const char* _something, const int& number) { /* ... */ }
Uh-oh. Now we're trying to use the value of _something
, which is a copy of something
, which is indeterminate. Undefined Behaviour and fire ensue.
You really shouldn't pass the value of a class member as parameter to its constructor, unless you have an infinite supply of fireproof chickens and eggs.
The behaviour you're looking for can be obtained by putting the default value in the call to the delegate constructor:
Test(const int& number) : Test("SOMETHING HERE!!!", number) { }
... or keeping it in a dedicated static variable:
static constexpr char *const defaultSomething = "SOMETHING HERE!!!";
Test(const int& number) : Test(defaultSomething, number) { }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With