如何解决POD 默认初始化如果是静态的和构造函数如果是自动的?
在下面的示例中,Y 和 X 给出警告“变量具有静态存储持续时间和非 POD 类型”(pclint,Autosar A3-3-2)。
struct Y {int t; Y() {t = 0;}};
class X {private: int t; public: X() {t = 0;}};
struct Z {int t;};
X x; // warning: variable 'x' has 'static' storage duration and non-POD type
Y y; // variable 'y' has 'static' storage duration and non-POD type
Z z;
我有两个问题。
编辑:在我的情况下,全局变量仅在标准命名空间中使用,并且数据由该命名空间中的全局函数访问。因此应该在访问数据之前执行构造函数。
一种解决方案可能是使用 C++ 包装类来初始化结构。是否有更简单/替代的解决方案,其中不会发生成员“int t”的未初始化使用?
解决方法
来自the AutoSAR C++14 Guidelines:
规则 A3-3-2(必需、实施、自动化)
静态和线程局部对象应为常量初始化。
基本原理
一般来说,使用非常量全局变量和静态变量会掩盖 API 的真正依赖,因为它们可以从任何地方访问 的源代码。因此,它使代码更难 维护、可读性和可测试性明显降低。
一个特殊的问题是构造函数和 静态变量的初始值设定项仅被部分调用 由 C++ 语言标准指定,甚至可以从构建中更改 建立。这可能会导致难以发现或调试的问题。
[...]
在调用构造函数之前会发生什么来证明警告是正确的?
该规则的基本原理是避免动态初始化适用于静态初始化的复杂规则,这是一个常见的原因,例如静态初始化失败。
如何避免 Y 和 X 出现的警告?如果与自动存储一起使用(对于 Z),我想避免可能的未初始化状态,因此我想保留构造函数或以其他方式达到目标。
对您的示例的简单修复是使它们的构造函数 constexpr
,这样 static
存储持续时间对象 x
和 y
是 constant-initialized instead of zero-initialized 作为一部分静态初始化:
执行常量初始化而不是零初始化 静态和线程局部 (C++11 起) 对象以及在所有其他对象之前 初始化。只有以下变量是常量初始化的:
[...]
- 由构造函数调用初始化的类类型的静态或线程本地对象,如果构造函数是 constexpr 和所有 构造函数参数(包括隐式转换)是常量 表达式, 以及如果构造函数初始化器中的初始化器 仅列表和类成员的大括号或等号初始值设定项 包含常量表达式。
例如(通过常量表达式将 t
数据成员的初始化移动到其默认成员初始值设定项):
struct Y {
int t{0};
constexpr Y() {}
};
class X {
private:
int t{0};
public:
constexpr X() {}
};
X x; // static initialization is constant-initialization
Y y; // static initialization is constant-initialization
或者在 t
构造函数的成员初始值设定项列表中初始化 constexpr
成员:
struct Y {
int t;
constexpr Y() : t{0} {}
};
class X {
private:
int t;
public:
constexpr X() : t{0} {}
};
最后,请注意 POD 不再是 C++11 的标准术语(已弃用),并且由于 AutoSAR C++14 指南自然适用于 C++14,因此应考虑完全放弃 POD 的概念班级类型;这同样适用于 pclint。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。