Почему я получаю ошибки компиляции после того, как я включил stdafx.h? - PullRequest
7 голосов
/ 18 октября 2011

Я пытаюсь написать программу, которая компилируется в Borland C ++ и Visual C ++. Для этого я добавляю #ifdef _MSC_VER, чтобы включить файл stdafx.h , когда исходный код компилируется в VS. Код компилируется и выполняется нормально в Borland C ++, но в 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 ]

11 голосов
/ 18 октября 2011

Способ, которым MSVC реализует предварительно скомпилированные заголовки, заключается в том, что компилятор игнорирует все, вплоть до строки, которая вводит предварительно скомпилированный заголовок, и начинает там с нуля.Поэтому, когда вы компилируете свою программу, она не «запоминает» строку #ifdef, поэтому строка #endif не имеет для нее никакого смысла.

Дело в том, что в этом нет ничего «MS»1005 *, за пределами своеобразной схемы именования [которую вы можете изменить в любом случае].Так зачем вообще блокировать включение в Borland?В худшем случае, вы перемещаете блок _MSC_VER в заголовок, и вы попадаете в ту же ситуацию, в которой находитесь сейчас, за исключением того, что есть один потраченный впустую файл включения.Или вы позволяете вашей системе сборки перенаправить #include в специфичный для Borland файл stdafx.h.

2 голосов
/ 18 октября 2011

Это должен быть эффект скомпилированного заголовка. Простое решение - отключить его в настройках проекта VS. Проблема в том, что компилятор сбрасывает свое состояние при обнаружении

#include "stdafx.h"

строка состояния, сохраненного в предварительно скомпилированном заголовочном файле. Таким образом, строка #ifdef... становится ignored, а строка #endif вызывает ошибку компиляции

0 голосов
/ 26 февраля 2018

Если мы переключим условный компилятор на 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 или традиционные средства защиты заголовков в этом макросе, как вы ожидаете. следовательно, мы можем собрать stdafx.h с помощью любого компилятора C / C ++, поскольку портируем наш макрос условного оператора into stdafx.h

0 голосов
/ 18 октября 2011

Другие прокомментировали проблему PCH. В отдельном примечании, в Borland, #pragma argsused должен быть присоединен к функции. Его цель состоит в том, чтобы указать компилятору, что аргументы функции не используются телом функции, поэтому он не выдает предупреждения «неиспользованный аргумент». Таким образом, вы не можете группировать #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;
}
...