为什么我会有运行时检查失败错误?

时间:2013-05-03 16:41:44

标签: c++ visual-studio-2010

我没有意识到.dll库对象类型依赖于在编译时发生的事情可能会出现问题直到我读到问题Could I ignore C4251 warning in this case?在契约中,如果库和程序的库编译设置使用库的方法不同,可能会出现一些错误。这是一个例子:

dll.h

 #include <iostream>
    #include <string>

    using namespace std;

    class __declspec(dllexport) HelloWorld
    {
    public:
    #ifdef DTEST
      int test;
    #endif
      HelloWorld();

    };

dll.cpp

#include "dll.h"

HelloWorld::HelloWorld()
{
#ifdef DTEST
    test=0;
#endif
}

exe.cpp

#include "dll.h"
#include <iostream>
using namespace std;

int main(void)
{
  HelloWorld myworld;

  return 0;
}

如果我编译dll.h和dll.cpp来创建带有DTEST定义的dll.lib和dll.dll但是在没有DTEST定义的情况下编译exe.cpp。我将有一个运行时检查失败#2错误。有人可以解释为什么我有这个错误。谢谢!

2 个答案:

答案 0 :(得分:2)

您有此错误,因为DTEST是预处理器宏,并且您没有为程序的所有部分一致地定义它。当代码到达实际编译器时,它会被完全删除,因此编译器不会发现问题。如果您为DTEST而不是dll.cpp定义exe.cpp,那么exe.cpp对于编译器将是这样的:

(...contents of <iostream>...)
(...contents of <string>...)

using namespace std;

class __declspec(dllexport) HelloWorld
{
public:
  HelloWorld();

};

(...contents of <iostream> again...)
using namespace std;

int main(void)
{
  HelloWorld myworld;

  return 0;
}

但是,dll.cpp将如下所示:

(...contents of <iostream>...)
(...contents of <string>...)

using namespace std;

class __declspec(dllexport) HelloWorld
{
public:
  int test;
  HelloWorld();

};

HelloWorld::HelloWorld()
{
    test=0;
}

此处的问题是dll.cpp,而exe.cppHelloWorld的含义有两种不同的看法:dll.cpp认为它包含test,但exe.cpp认为它没有。有一个运行时检查可以捕获这种不匹配,这就是你所看到的。

答案 1 :(得分:1)

编译器看到的是预处理器扩展的结果。 在您的示例中,编译器会看到:

class HelloWorld
{
public:
    int test;
    HelloWorld();
};
<{1>}中的

dll.cpp
class HelloWorld { public: HelloWorld(); }; 中的

。相同的类,两个不同的定义。那是 违反一个定义规则,导致 未定义的行为。

这与C4251警告无关(如果有的话) 我理解正确,只关注不同之间的联系 DLL)的