如何强制C++接触枚举定义冲突的链接器?

发布于 2025-02-05 04:48:03 字数 688 浏览 0 评论 0原文

我有这两个源文件可以毫无问题地编译和链接。

A.CPP

enum class numbers
{
    one,
    two,
};

const char* getName(numbers number)
{
    switch (number)
    {
    case numbers::one:
        return "one";
        break;
    case numbers::two:
        return "two";
        break;
    }
}

B.CPP

#include <iostream>

enum class numbers
{
    zero,
    one,
    two,
};

const char* getName(numbers number);

void print(numbers number)
{
    std::cout << getName(number);
}

int main()
{
    print(numbers::one);
    return 0;
}

,您可以看到每个文件中相同的枚举类别的定义不同。我正在寻找一种方法来捕捉不同翻译单元中枚举类别的冲突(在我们非常大的代码库中引起错误)。在这种情况下,是否有任何编译器/链接器能够产生错误?

I have these two source files that compile and link without any problem.

a.cpp

enum class numbers
{
    one,
    two,
};

const char* getName(numbers number)
{
    switch (number)
    {
    case numbers::one:
        return "one";
        break;
    case numbers::two:
        return "two";
        break;
    }
}

b.cpp

#include <iostream>

enum class numbers
{
    zero,
    one,
    two,
};

const char* getName(numbers number);

void print(numbers number)
{
    std::cout << getName(number);
}

int main()
{
    print(numbers::one);
    return 0;
}

As you can see the same enum class is defined differently in each file. I am looking for a way to catch these kind of conflicts of enum classes (causing bugs in our very very big code base) in different translation units. Does any compiler/linker has the capability to generate error in such situation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

尴尬癌患者 2025-02-12 04:48:04

显示的错误是违反一个定义规则

C ++标准不需要编译器或链接器即可报告诊断违反一个定义规则时。即“不需要诊断”。

换句话说:您的C ++编译器不需要报告此特定错误。这是因为在许多情况下,由于低水平的技术实施详细信息如何在某些特定的操作系统或平台上编译和链接代码,因此根本不可能从技术上检测到对一个定义规则的违反。

通常:在每个现代C ++编译器的兴趣中,报告尽可能多的有用诊断。换句话说:如果C ++编译器可以检测到ODR违规,则很容易就不会被侵入。如果您的C ++编译器未对ODR违规产生诊断,则不太可能有任何隐藏的开关或按钮可以按下以使错误出现。

The shown error is a violation of the One Definition Rule.

The C++ standard does not require either the compiler or a linker to report a diagnostic when the One Definition Rule is violated. I.e. "no diagnostic required".

In other words: your C++ compiler is not required to report this specific error. This is because in many cases it's simply not possible to technically detect a violation of the one definition rule, due to low-level technical implementation details of how code gets compiled and linked on some particular operating system, or platform.

In general: it is in every modern C++ compiler's interest to report as many useful diagnostics as possible. In other words: if it's possible for a C++ compiler to detect an ODR violation, it would readily do so without being prodded into it. If your C++ compiler does not produce a diagnostic for an ODR violation, it is unlikely that there's any hidden switch or a button that can be pushed in order to make the error come out.

带刺的爱情 2025-02-12 04:48:04

连接器不可能抓住这一点。枚举类别的定义只是定义了编译器将用于生成代码的许多编译时间常数。没有针对接头可以看到并警告复制物的任何枚举标识符创建的对象。

我也不明白为什么这个代码根本是一个问题。您没有导出类型,而是仅在编译单元内使用。两个定义之间没有交叉。尽管标准可能指出一个定义规则,但我没有看到实际问题。

但是,如果您尝试创建一个问题,则将类型放入标头文件中并尝试将其包含在内,则编译器将以重复的定义失败。从A.CPP和B.CPP中调用getName()的任何尝试都将包括AH和BH,然后失败。因此,除非您对编写标题文件不粗心并使用未定义的前瞻性声明,否则您将始终在问题之前出现错误。

There is no possibility for the linker to catch this. An enum class definition just defines a number of compile time constants that the compiler will use to generate code. There is no object created for any of the identifiers of the enum that the linker could see and warn about duplicates.

I also don't see why this code would be a problem at all. You aren't exporting the type, it's used solely inside the compilation unit. There is no cross over between the two definitions. While the standard might point at the one definition rule I see no practical problem.

But if you try to create a problem, if you put the type into the header files and try to include both then the compiler will fails with a duplicate definition. Any attempt to call getname() from both a.cpp and b.cpp or use the enums would include a.h and b.h and then fail. So unless you are careless with writing your header files and use forward declarations without definitions you will always get an error before it matters.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文