【发布时间】:2020-10-25 23:09:20
【问题描述】:
在我们的项目中,我们经常使用这样的构造(为了清晰起见,我们实际上使用了更安全的版本):
struct Info
{
Info(int x, int y) : m_x(x), m_y(y)
{}
int m_x;
int m_y;
};
struct Data
{
static const Info M_INFO_COLLECTION[3];
};
const Info Data::M_INFO_COLLECTION[] = // global-constructors warning
{
Info(1, 2),
Info(10, 9),
Info(0, 1)
};
M_INFO_COLLECTION 可以包含大量数据点。初始化部分位于 cpp 文件中,该文件通常由代码生成。
现在,这种结构在我们的代码库中为我们提供了相当数量的global-constructors-warnings。我读过in a blog post,在-Weverything 组中使用警告对于夜间构建来说是个坏主意,我同意,甚至是clang docdoes not recommend to use it。
由于我无法决定关闭警告,我可以使用a helpful trick 来消除警告(以及潜在的静态初始化命令失败),方法是将静态成员到一个初始化并返回一个局部静态变量的函数中。
但是,由于我们的项目通常不使用动态分配的内存,所以原来的想法必须在没有指针的情况下使用,这会导致deinitialization problems当我的Data类被其他对象使用时很奇怪方式。
所以,长话短说:global-constructors 警告指向一段我可以安全审查的代码,因为我知道Data 类的作用。如果 other 类以特定方式使用Data,我可以使用可能导致问题的解决方法摆脱它,但这不会产生警告。我的结论是,我最好保留代码原样并忽略警告。
所以现在我遇到了一堆警告,在某些情况下可能指向一个 SIOF 并且我想解决它,但是这些警告被我故意不想修复的堆积如山的警告所掩盖,因为修复实际上会使事情变得更糟。
这让我想到了我的实际问题:clang 对警告的解释是否过于严格?根据我有限的编译器理解,编译器是否应该意识到在这种特殊情况下,静态成员 M_INFO_COLLECTION 不可能导致 SIOF,因为它的所有依赖项都是非静态的?
我稍微解决了这个问题,甚至这段代码也收到了警告:
//at global scope
int get1()
{
return 1;
}
int i = get1(); // global-constructors warning
正如我所料,这很好用:
constexpr int get1()
{
return 1;
}
int i = 1; // no warning
int j = get1(); // no warning
这对我来说看起来相当微不足道。我是否遗漏了什么或者应该能够抑制这个例子的警告(也可能是我上面的原始例子)?
【问题讨论】:
-
在源代码本身中根据需要禁用警告
#pragma clang diagnostic ignored "-Wglobal-constructors"。对于我的项目,我在项目中禁用了“嘈杂的蟋蟀”警告,但如果这不是一个选项,您可以在代码中根据具体情况进行操作。 -
@cigien 我已经发现了这个问题,它让我想到了使用带有局部静态变量的函数的想法。在这个问题中,我想解决为什么 clang 无法处理明显没有问题的情况。我同意这两个问题密切相关,但存在细微差别。
-
@Eljay 这是个好主意。我会检查我是否可以通过我们的部门来解决这个问题,尽管我更愿意在全球范围内关闭。
-
好的,听起来不错。我会留下评论,这样再加上你的回复应该确保它不会被关闭。这些标题至少使它们看起来非常相似:)
标签: c++ clang compiler-warnings