[英]Delegating constructor gives segmentation fault when using class field for argument
实际上,分段错误发生在我试图编译的另一个程序中,这是因为这种行为。
我的问题是:
这是一个错误还是我的错?
可以任何方式重现(即使something
字段是私有的或受保护的),这是我的例子:
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;
}
以下是编译时发生的情况:
g++ main.cc -Os -o main
并运行:
./main
输出是:
pi@pi:~/ $ ./main
A"�~ <-- this is random
345
asdasdad
34523
但是当我使用-O0
或-O1
或-O2
启用优化时......输出只是一个新行:
pi@pi:~/ $ ./main
pi@pi:~/ $
G ++版本:
pi@pi:~/ $ g++ --version
g++ (Raspbian 6.3.0-18+rpi1) 6.3.0 20170516
const char* something = "SOMETHING HERE!!!";
正如其名称所示,右侧的default-initializer仅在未在构造函数的初始化列表中提供显式初始值设定项时使用。 让我们看看你的:
Test(const int& number) : Test(something, number) { }
好的,我们委托给另一个构造函数。 其他构造函数将执行完全初始化,因此不使用默认初始值设定项。 但是......我们正在传递的未初始化值something
作为参数。
Test(const char* _something, const int& number) { /* ... */ }
嗯,哦。 现在我们正在尝试使用_something
的值,这是something
的副本,这是不确定的。 未定义的行为和火灾随之而来。
除非你有无限量的防火鸡和鸡蛋,否则你真的不应该将类成员的值作为参数传递给它的构造函数。
您可以通过将默认值放在对委托构造函数的调用中来获取您正在寻找的行为:
Test(const int& number) : Test("SOMETHING HERE!!!", number) { }
...或将其保存在专用的静态变量中:
static constexpr char *const defaultSomething = "SOMETHING HERE!!!";
Test(const int& number) : Test(defaultSomething, number) { }
这是一个错误还是我的错?
哦,这是你的错。 默认成员初始值设定项仅用于在非委派构造函数中初始化成员对象。 根据[class.base.init] / 9 ,强调我的:
在非委托构造函数中 ,如果给定的可能构造的子对象不是由mem-initializer-id指定的(包括没有mem-initializer-list的情况,因为构造函数没有ctor-initializer),那么
- 如果实体是具有默认成员初始值设定项的非静态数据成员,则[dcl.init]中指定的实体从其默认成员初始值设定项初始化;
因此,当您将其传递给目标构造函数时, something
内容不会被初始化。 你的程序有不确定的行为,并且破产了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.