什么可能会覆盖 main() 函数的返回代码?

3

我遇到了一个比较奇怪的问题,一直没有想明白。

我有一个测试用例,它应该捕获错误并从主函数返回相应的错误代码。但是,在有些情况下,无论错误代码是否为非零值,程序在测试运行中仍会返回0。

抛出的异常类为:

class exit_request {
public:
    explicit exit_request(int code = 0) : m_code(code) {}
    int code() const { return m_code; }
private:
    int m_code;
};

测试用例的代码如下:
int main(int argc, char* argv[])
{
    try {
        // Do some test case stuff
        // Eventually, due to the supplied command line arguments,
        // we expect an exit_request() to be thrown from within
        // library code.       
    }
    catch (exit_request& exp) {
        std::cout << "Exit Request:" << exp.code() << std::endl;
        return exp.code();
    }
    catch (std::exception& err) {
        std::cout << "Error: " << err.what() << std::endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

在许多次运行该测试用例时,一切都如预期地工作:抛出exit_request()异常,被捕获,打印exp.code()(其值为2),并且从进程返回的返回代码为2。
然而,很少情况下,尽管exp.code()打印为2,但是从进程返回的返回代码是0(即没有失败)。
有人能帮忙解释一种可能发生这种情况的情况吗?即在进程退出之前将从main函数返回的返回值从非零更改为零?
这发生在Windows 7(x64)上,使用MSVC ++ 2010 Express构建32位应用程序。我没有在我们的其他Windows或Linux平台或编译器上看到这个奇怪的故障,但这并不一定意味着它在这些环境中不能发生。

1
尝试添加catch(...)以确保捕获所有异常。 - Adrian Cornish
2个回答

1
如果您有任何调用exit(0)atexit处理程序,或者任何静态存储期对象其析构函数执行该操作,那么这可能解释了您所看到的情况。它们会在您的return语句之后执行。这是未定义的行为,这可能解释了为什么您只有时会看到它发生。

谢谢。这可能就是了,我会进一步调查。 - Danny S
哎呀,不幸的是我们没有任何活动的atexit()函数,这意味着它可能在静态对象析构函数中。我查看了我们代码中最明显的一些部分,但它们似乎被正常调用,即使在返回代码为0(预期为2)的运行中也是如此。所以很可能我错过了某些东西。 - Danny S
你可以在内部观察到这个问题吗?使用调试器。在“ExitProcess”上设置一个断点,看看你是如何到达那里的。 - Rob Kennedy

0
也许你没有正确地抛出异常... 我的意思是,在try块中调用的函数或处理过程中,你抛出了其他类型的异常。 尝试为此编写一个默认catch块

肯定抛出和捕获正确的异常 - 在catch块中有一个打印exit_request的语句,我可以看到它被打印到标准输出。无论如何,感谢您的建议。 - Danny S

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接