gpt4 book ai didi

c++ - 未使用的函数能否根据 C++14 实例化具有副作用的变量模板?

转载 作者:太空狗 更新时间:2023-10-29 20:20:07 26 4
gpt4 key购买 nike

这是我的代码:

#include <iostream>

class MyBaseClass
{
public:
static int StaticInt;
};

int MyBaseClass::StaticInt = 0;

template <int N> class MyClassT : public MyBaseClass
{
public:
MyClassT()
{
StaticInt = N;
};
};

template <int N> static MyClassT<N> AnchorObjT = {};

class UserClass
{
friend void fn()
{
std::cout << "in fn()" << std::endl; //this never runs
(void)AnchorObjT<123>;
};
};

int main()
{
std::cout << MyBaseClass::StaticInt << std::endl;
return 0;
}

输出是:

123

...表示MyClassT()尽管如此 fn() 还是调用了构造函数从未被调用。

测试于 gccclang-O0 , -O3 , -Os甚至-Ofast


问题

根据 C++ 标准,这个程序是否有未定义的行为?

换句话说:如果更高版本的编译器设法检测到 fn()永远不会被调用它们能否在运行构造函数的同时优化掉模板实例化?

能否以某种方式使此代码具有确定性,即强制构造函数运行 - 引用函数名称 fn或模板参数值 123UserClass之外?


更新:版主截断了我的问题并建议进一步截断。详细原版可以查看here .

最佳答案

模板实例化是代码的一个函数,而不是任何一种动态运行时条件的函数。举个简单的例子:

template <typename T> void bar();

void foo(bool b) {
if (b) {
bar<int>();
} else {
bar<double>();
}
}

两者都是 bar<int>bar<double>在这里被实例化,即使foo永远不会被调用,即使 foo仅使用 true 调用.

对于变量模板,具体规则为[temp.inst]/6 :

Unless a variable template specialization has been explicitly instantiated or explicitly specialized, the variable template specialization is implicitly instantiated when it is referenced in a context that requires a variable definition to exist or if the existence of the definition affects the semantics of the program.

在你的函数中:

friend void fn() 
{
(void)AnchorObjT<123>;
};

AnchorObjT<123>在需要定义的上下文中被引用(无论 fn() 是否被调用,甚至在这种情况下,甚至可以调用),因此它被实例化。

但是AnchorObjT<123>是一个全局变量,所以它的实例化意味着我们有一个在 main() 之前构造的对象- 当我们输入 main() 时, AnchorObjT<123>的构造函数将已经运行,设置 StaticInt123 .请注意,我们不需要实际运行 fn()调用此构造函数 - fn()在这里的作用只是实例化变量模板,它的构造函数在别处调用。

打印 123 是正确的预期行为。


请注意,虽然该语言需要全局对象 AnchorObjT<123>存在,链接器可能仍然是对象,因为没有对它的引用。假设您的真实程序对该对象执行更多操作,如果您需要它存在,您可能需要对其执行更多操作以防止链接器删除它(例如 gcc 具有 used attribute )。

关于c++ - 未使用的函数能否根据 C++14 实例化具有副作用的变量模板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53683119/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com