简体   繁体   English

我在 Clang 和 GCC 中发现了错误吗?

[英]Have I found a bug in Clang and GCC?

main.cpp:主.cpp:

#include <iostream>

struct Cls {
    static void some_method() {
        std::cout << __FILE__ << ": " << __LINE__ << std::endl;
    }
};

extern void call_some_method();

void never_caled() {
    Cls::some_method();  // (1)
}

int main() {
    call_some_method();
    return 0;
}

cls.cpp: cls.cpp:

#include <iostream>

struct Cls {
    static void some_method() {
        std::cout << __FILE__ << ": " << __LINE__ << std::endl;
    }
};

void call_some_method() {
    Cls::some_method();
}

When (1) is commented, call_some_method() write "/home/maxim/CLionProjects/bug/cls.cpp: 5" to std::cout.当 (1) 被注释时, call_some_method() 将 "/home/maxim/CLionProjects/bug/cls.cpp: 5" 写入 std::cout。

When (1) is uncommented, call_some_method() write "/home/maxim/CLionProjects/bug/main.cpp: 5" to std::cout.当 (1) 未注释时, call_some_method() 将 "/home/maxim/CLionProjects/bug/main.cpp: 5" 写入 std::cout。

How it can be possible for different outputs?不同的输出怎么可能?

__FILE__ and __LINE__ are macros that are expanded by the pre-processor. __FILE____LINE__是由预处理器扩展的宏。 Since those macros are in different files, and depend on the files they are used in, they expand to different token sequences.由于这些宏位于不同的文件中,并且取决于使用它们的文件,因此它们会扩展为不同的标记序列。

That means that your definition of Cls::some_method is different across different translation units.这意味着您对Cls::some_method定义在不同的翻译单元中是不同的。 This violates the one-definition-rule ( ODR ) which requires, among other things, that there be exactly one definition of a particular entity in your entire program.这违反了单一定义规则 ( ODR ),该规则要求在整个程序中对特定实体只有一个定义。 If there are multiple definitions, that's fine, so long as the token sequence of those definitions is identical in every translation unit, and those tokens mean the same thing when they are parsed.如果有多个定义,那没问题,只要这些定义的标记序列在每个翻译单元中都是相同的,并且这些标记在解析时的含义相同。

This is obviously not true in your case, so you are violating the ODR, which makes the program ill-formed (No Diagnosis Required).这显然不适用于您的情况,因此您违反了 ODR,这使得程序格式错误(无需诊断)。 This means the compiler is not obliged to give you an error, but if it does produce a program, executing that program invokes undefined behavior ( UB ).这意味着编译器没有义务给你一个错误,但如果它确实产生了一个程序,执行该程序会调用未定义的行为 ( UB )。 So your program could do anything at all, including producing the output that you are seeing.所以你的程序可以做任何事情,包括产生你看到的输出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM