函数没有地址,可能是由于编译器优化所致

kov*_*and 1 c++ visual-studio visual-studio-2022

在 Visual Studio 2022 中,如果我尝试在“监视”窗口中调用简单结构的函数,则会收到“函数没有地址,可能是由于编译器优化”错误。如果我在“监视”窗口中调用模板函数,则会收到此错误:“MyStruct”类没有成员“Multi”。如果我在源代码中使用一次这些函数,那么它们也将开始在 Watch 窗口中工作,但是如何使它们在 Watch 窗口中工作而不必在源代码中使用它们呢?

我的代码:

struct MyStruct
{
    int i;
    MyStruct(int _i) : i{ _i } {}
    int Add(int x) { return i + x; };

    template<typename _Tp> inline _Tp Multi(int x)
    {
        return (_Tp)i * x;
    }
};

int main()
{
    MyStruct s1(2);
    //auto x1 = s1.Add(5);
    //auto x2 = s1.Multi<double>(9);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

和监视窗口: 在此输入图像描述

我正在运行调试版本。链接器 -> 调试 -> 生成调试信息设置为“/DEBUG:FULL”并且禁用优化:禁用 (/Od)。

Sam*_*hik 7

如何使它们在“监视”窗口中工作而不必在源代码中使用它们

你不能。从根本上讲,C++ 根本不是这样工作的。模板不是函数。里面没有代码啊 从最字面的意义上来说,从定义和名称来看,它是一个函数的模板。换句话说,它只是实际功能的蓝图。

当代码引用模板并提供模板的参数(显式地或通过模板参数推导)时,只有这样您才能得到一个实际的、诚实的函数。用实际代码。这个过程称为模板实例化

在模板函数被实例化之前,它实际上并不作为程序的一部分存在,并且调试器无法调用任何内容。调试器可以上下搜索,但它不会找到任何它可以实际调用的东西。它不存在。但是,当模板被实例化时,作为实际代码的一部分,调试器可以在程序的符号表中找到其修改后的符号,引用实际函数并调用它。

现在,理论上,调试器可以将 C++ 编译器作为调试器本身的一部分,或者使用外部 C++ 编译器,以某种方式将模板实例化为实际函数并调用它。但是,实际上,不太可能有某种调试器实际上是这样工作的。

  • 在这种情况下,我会使用“模板”这个词,就像艺术家的模板一样。我发现 *stencil* 有时不那么令人困惑。:-) (3认同)