在有条件地包含stdafx.h之后,为什么会出现编译错误?

时间:2011-10-18 02:07:07

标签: c++ visual-studio compiler-errors c++builder conditional-compilation

我正在尝试编写一个用Borland C ++和Visual C ++编译的程序。为此,我在VS下编译源时添加#ifdef _MSC_VER以包含 stdafx.h 文件。代码在Borland C ++中编译并执行OK,但在VS中,它失败了:

  

错误C1020:意外#endif

#ifdef _MSC_VER //I'm in VS
#include "stdafx.h"
#endif //this line doesn't compile in VS


#ifdef __BORLANDC__   //I'm in Borland
#pragma hdrstop
#pragma argsused
#endif

#include <iostream>

int main(int argc, char* argv[])
{
    std::cout << "Hello" << std::endl;
    std::cin.get();
    return 0;
}

我如何解决此错误?

4 个答案:

答案 0 :(得分:11)

MSVC实现预编译头的方式基本上是编译器忽略引入预编译头的行的所有内容,并从头开始。因此,当您编译程序时,它不会“记住”#ifdef行,因此#endif行对它没有任何意义。

问题是,除了特殊的命名方案[无论如何你可以改变]之外,stdafx.h没有任何固有的“MS”。那么为什么要首先阻止在Borland中加入?在最糟糕的情况下,您将_MSC_VER块移动到标题中,最终会出现与您现在相同的情况,除非有一个浪费的包含文件。或者,您让构建系统将#include重定向到特定于Borland的stdafx.h文件。

答案 1 :(得分:2)

那必须是预编译的标题功能效果。简单的解决方案是在VS项目设置中将其关闭。 问题是,编译器在遇到

时会重置其状态
#include "stdafx.h"

行到预编译头文件中保存的状态。因此#ifdef...行变为ignored并且#endif行导致编译器错误

答案 2 :(得分:0)

其他人评论了PCH问题。另外,在Borland中,#pragma argsused必须附加到一个函数。它的目的是单独向编译器函数体不使用函数的参数,因此它不会发出“unused arguments”警告。因此,您无法将#pragma hdrstop#pragma argsused分组到同一#ifdef块中。你需要将它们分开,例如:

#include "stdafx.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#include <iostream>

#ifdef __BORLANDC__
#pragma argsused
#endif
int main(int argc, char* argv[])
{
  std::cout << "Hello" << std::endl;
  std::cin.get();
  return 0;
}

一个更简单的解决方案是简单地注释掉参数名称:

#include "stdafx.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#include <iostream>

int main(int /*argc*/, char* /*argv[]*/)
{
  std::cout << "Hello" << std::endl;
  std::cin.get();
  return 0;
}

答案 3 :(得分:0)

如果我们将编译器条件切换到stdafx.h,我们可以避免此错误。  例如,可以在 stdafx.h

中定义以下代码行
    ********************* stdafx.h **************************
    #pragma once

    #if defined (_MSC_VER)

    #include "targetver.h"

    #define WIN32_LEAN_AND_MEAN             
    // Windows Header Files:
    #include <windows.h>
    #endif 
    *********************************************************

您可以按预期在此宏条件中切换pragma once或传统的标题保护。 因此,我们可以使用任何C / C ++编译器构建stdafx.h,因为我们将宏条件语句into移植到stdafx.h