0

所以我正在编写这个简单的 CLI 工具,而且我的代码不会太繁琐,这基本上是发生了什么:

bool IsThing()
{
    // stuff goes here
    return false;
}

int _tmain(int argc, _TCHAR* argv[])
{
    bool IsThing_ = IsThing();
    if ( IsThing_ )
    {
        printf( "foo\n" );
        return 1;
    }

    return 0;
}

当我运行这段代码时,我明确地尝试失败IsThing(),甚至从字面上删除其中的所有内容,除了return false. 但是,每一次,我都会得到一个返回码1

为了调试,我IsThing()_tmain(). 最让我沮丧的是,在里面的断点处IsThing(),VS会告诉我

没有可执行代码与此行相关联。

相反,当我单步执行 main 函数时,它实际上会转到bool IsThing_ = IsThing();,然后检查 if 条件而无需进入实际函数,并且会立即跳到条件内的内容。

为什么我的函数调用不起作用?

4

2 回答 2

2
bool IsThing()
{
    // stuff goes here
    return false;
}

int _tmain(int argc, _TCHAR* argv[])
{
    bool IsThing_ = IsThing();
    if ( IsThing_ )
    {
        printf( "foo\n" );
        return 1;
    }

    return 0;
}

在发布模式下,Visual Studio 会将此代码转换为:

int _tmain(int argc, _TCHAR* argv[])
{
    return 0;
}

当然,由于IsThing不再需要,因此不会为其生成任何代码,因此您无法在其中设置断点。

现在,如果您将足够的代码填充到实际执行某些操作的函数中(例如文件 I/O)并且不对 的返回进行硬编码false,那么编译器可能确实会将其变成一个可以获取的函数叫。但是如今的编译器非常擅长消除不会产生任何“有意义”的代码。

我不认为这里有什么大谜团——这只是编译器的工作方式。

于 2013-03-11T20:50:24.223 回答
1

您正在使用最有可能使用/O1 或 /O2 优化的发布配置进行编译,这旨在使您的代码更快更小。这意味着在编译期间这个函数:

bool IsThing() { return false; }

正在内联,这导致您main相当于:

int _tmain(int argc, _TCHAR* argv[])
{
    bool IsThing_ = false;
    if ( IsThing_ )
    {
        printf( "foo\n" );
        return 1;
    }
    return 0;
}

甚至if可能会省略语句的主体,这将导致:

int _tmain(int argc, _TCHAR* argv[])
{
    return 0;
}

这也是使用Debug配置为您工作的原因。您可以尝试转到项目属性并在C/C++ -> 优化下将优化选项更改为Disabled (/Od),您应该能够看到,在此更改之后,您的断点将为您工作:)

于 2013-03-11T20:52:53.150 回答