模板静态成员定义取决于传递给链接器的顺序

问题描述 投票:1回答:1

以下代码为模板静态字段成员提供2个定义,每个定义使用不同的值定义template1<int>::x

人们希望链接器拒绝这样的重新定义,因为它们具有不同的值。

但是g ++和MSVC都通过了编译和链接,并且使用哪个定义取决于将源传递给链接器的顺序。

此行为是否符合C ++标准,未定义的行为或链接器错误?

my_template.h

template <class T>
class template1
{
public:
    static int x;
};

Src2.cpp

#include <stdio.h>
#include "my_template.h"

template <class T>
int template1<T>::x = 2; 

void my_func() // definition
{
    printf("my_func: template1<int>::x = %d\n", template1<int>::x); // definition of X to 2.
    printf("my_func: template1<char>::x = %d\n", template1<char>::x); // definition of X to 2.
}

Main.cpp

#include <cstdio>
#include "my_template.h"

template <class T>
int template1<T>::x = 1;

void my_func();

int main()
{
    printf("main: template1<int>::x = %d\n", template1<int>::x); // definition of X to 1.
    my_func();
    return 0;
}

使用g ++编译(MinGW.org GCC Build-20200227-1)9.2.0+

Compile1

g++ -o prog Src2.cpp Main.cpp

Output1

main: template1<int>::x = 2
my_func: template1<int>::x = 2
my_func: template1<char>::x = 2

Compile2

g++ -o prog Main.cpp Src2.cpp

Ouput2

main: template1<int>::x = 1
my_func: template1<int>::x = 1
my_func: template1<char>::x = 2

也观察到

Microsoft (R) C/C++ Optimizing Compiler Version 19.25.28612 for x86

当我用-S标志反汇编代码时,每个编译单元都定义了相同的符号名称。

Nightra一起工作。

c++ templates linker g++
1个回答
2
投票

这违反了ODR(如果使用实体,则它必须具有exactly一个定义)。因此该程序具有UB。

编译器无法对此进行诊断,因为每个翻译单元都可以。从理论上讲,链接器可以]诊断此问题,但实际上,它不会执行此操作。

© www.soinside.com 2019 - 2024. All rights reserved.