8

Estoy tratando de escribir un programa que compila en Borland C++ y Visual C++. Para hacer esto, agrego #ifdef _MSC_VER para incluir el archivo stdafx.h cuando la fuente se compila en VS. El código se compila y ejecuta bien en Borland C++, pero en VS, falla:¿Por qué obtengo errores de compilación después de incluir condicionalmente stdafx.h?

error C1020: #endif inesperada

#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; 
} 

¿Cómo puedo corregir este error?

Respuesta

11

La forma MSVC implementa encabezados precompilados, es básicamente que el compilador ignora todo hasta la línea que lleva en el encabezado precompilado, y comienza de nuevo desde cero allí. Entonces, cuando compila su programa, no "recuerda" la línea #ifdef, por lo que la línea #endif no tiene sentido.

El problema es que no hay nada intrínsecamente "MS" en stdafx.h, más allá del peculiar esquema de nombres [que puede cambiar de todos modos]. Entonces, ¿por qué molestarse en bloquear la inclusión en Borland en primer lugar? En el peor de los casos, mueve el bloque _MSC_VER al encabezado y termina en la misma situación en la que se encuentra ahora, excepto que hay un único archivo de inclusión desperdiciado. O permite que su sistema de compilación redirija el #include a un archivo stdafx.h específico de Borland.

2

Debe tener el efecto de función de encabezado precompilado. La solución simple es apagarlo en la configuración del proyecto VS. El problema es, compilador restablece el estado en que se encuentra la línea

#include "stdafx.h" 

al estado guardado en el archivo de encabezado precompilado. Así que la convierte en #ifdef...ignored y #endif línea provoca error del compilador

1

Otros comentaron sobre el problema de PCH. En una nota aparte, en Borland, #pragma argsused tiene que adjuntarse a una función. Su propósito es individualizar al compilador que los argumentos de la función no son utilizados por el cuerpo de la función para que no emita advertencias de "argumento no utilizado". Como tal, no puede agrupar #pragma hdrstop y #pragma argsused en el mismo bloque #ifdef. Es necesario separarlos, por ejemplo:

#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; 
} 

Una solución más simple es simplemente comentar los nombres de los argumentos en su lugar:

#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; 
} 
5

Si cambiamos compilador condicional en que stdafx.h podemos evitar este error. por ejemplo siguientes líneas de código se pueden definir en stdafx.hy

********************* stdafx.h ************************** 
    #pragma once 

    #if defined (_MSC_VER) 

    #include "targetver.h" 

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

puede cambiar pragma once o tradicionales guardias de cabecera dentro de esta macro condicional según lo previsto. por lo tanto, podemos construir stdafx.h con cualquier compilador C/C++ ya que portamos nuestra declaración condicional de macro intostdafx.h

Cuestiones relacionadas