#if, #elif, #else y directivas de #endif (C/C++)#if, #elif, #else, and #endif directives (C/C++)

La directiva #if , con las directivas #elif, #elsey #endif , controla la compilación de partes de un archivo de código fuente.The #if directive, with the #elif, #else, and #endif directives, controls compilation of portions of a source file. Si la expresión que escribe (después de la #if) tiene un valor distinto de cero, el grupo de líneas inmediatamente después de la directiva de #if se mantiene en la unidad de traducción.If the expression you write (after the #if) has a nonzero value, the line group immediately following the #if directive is kept in the translation unit.

GramáticaGrammar

condicional : conditional :
    If-Part Elif- PartsOPC else-PartOPC endif-line    if-part elif-partsopt else-partopt endif-line

si-parte : if-part :
    texto if-line    if-line text

If-line : if-line :
    #if expresión constante    #if constant-expression
    #ifdef identificador de #ifdef    #ifdef identifier
    #ifndef identificador de #ifndef    #ifndef identifier

Elif-partes : elif-parts :
    texto de la línea Elif    elif-line text
    texto de la línea Elif-Parts    elif-parts elif-line text

Elif-línea : elif-line :
    #elif expresión constante    #elif constant-expression

else-Part : else-part :
    texto de la línea adicional    else-line text

else-line : else-line :
    #else    #else

endif-línea : endif-line :
    #endif    #endif

ObservacionesRemarks

Cada directiva de #if de un archivo de código fuente debe coincidir con una directiva de cierre #endif .Each #if directive in a source file must be matched by a closing #endif directive. Puede aparecer cualquier número de directivas de #elif entre las directivas #if y #endif , pero se permite como máximo una directiva #else .Any number of #elif directives can appear between the #if and #endif directives, but at most one #else directive is allowed. La directiva #else , si está presente, debe ser la última Directiva antes de #endif.The #else directive, if present, must be the last directive before #endif.

Las directivas #if, #elif, #elsey #endif se pueden anidar en las partes de texto de otras directivas de #if .The #if, #elif, #else, and #endif directives can nest in the text portions of other #if directives. Cada directiva anidada #else, #elifo #endif pertenece a la Directiva de #if precedente más cercana.Each nested #else, #elif, or #endif directive belongs to the closest preceding #if directive.

Todas las directivas de compilación condicional, como #if y #ifdef, deben coincidir con una directiva de cierre #endif antes del final del archivo.All conditional-compilation directives, such as #if and #ifdef, must match a closing #endif directive before the end of file. De lo contrario, se genera un mensaje de error.Otherwise, an error message is generated. Cuando las directivas de compilación condicional están contenidas en archivos de inclusión, deben cumplir las mismas condiciones: no debe haber directivas de compilación condicional sin coincidencia al final del archivo de inclusión.When conditional-compilation directives are contained in include files, they must satisfy the same conditions: There must be no unmatched conditional-compilation directives at the end of the include file.

El reemplazo de macros se realiza dentro de la parte de la línea que sigue a un comando de #elif , por lo que se puede usar una llamada de macro en Constant-Expression.Macro replacement is done within the part of the line that follows an #elif command, so a macro call can be used in the constant-expression.

El preprocesador selecciona una de las apariciones de texto dadas para su posterior procesamiento.The preprocessor selects one of the given occurrences of text for further processing. Un bloque especificado en texto puede ser cualquier secuencia de texto.A block specified in text can be any sequence of text. Puede ocupar más de una línea.It can occupy more than one line. Normalmente, el texto es el texto de programa que tiene significado para el compilador o el preprocesador.Usually text is program text that has meaning to the compiler or the preprocessor.

El preprocesador procesa el texto seleccionado y lo pasa al compilador.The preprocessor processes the selected text and passes it to the compiler. Si el texto contiene directivas de preprocesador, el preprocesador realiza esas directivas.If text contains preprocessor directives, the preprocessor carries out those directives. Solo se compilan los bloques de texto seleccionados por el preprocesador.Only text blocks selected by the preprocessor are compiled.

El preprocesador selecciona un solo elemento de texto mediante la evaluación de la expresión constante que sigue a cada #if o #elif Directiva hasta que encuentra una expresión constante true (distinto de cero).The preprocessor selects a single text item by evaluating the constant expression following each #if or #elif directive until it finds a true (nonzero) constant expression. Selecciona todo el texto (incluidas otras directivas de preprocesador que comienzan por # ) hasta su #elif, #elseo #endifasociados.It selects all text (including other preprocessor directives beginning with #) up to its associated #elif, #else, or #endif.

Si todas las apariciones de Constant-Expression son false o si no aparecen directivas de #elif , el preprocesador selecciona el bloque de texto después de la cláusula #else .If all occurrences of constant-expression are false, or if no #elif directives appear, the preprocessor selects the text block after the #else clause. Cuando no hay ninguna cláusula #else y todas las instancias de Constant-Expression en el bloque #if son false, no se selecciona ningún bloque de texto.When there's no #else clause, and all instances of constant-expression in the #if block are false, no text block is selected.

Constant-Expression es una expresión constante entera con estas restricciones adicionales:The constant-expression is an integer constant expression with these additional restrictions:

  • Las expresiones deben tener un tipo entero y solo pueden incluir constantes enteras, constantes de caracteres y el operador definido .Expressions must have integral type and can include only integer constants, character constants, and the defined operator.

  • La expresión no puede utilizar sizeof o un operador de conversión de tipos.The expression can't use sizeof or a type-cast operator.

  • Es posible que el entorno de destino no pueda representar todos los intervalos de enteros.The target environment may be unable to represent all ranges of integers.

  • La traducción representa el tipo int de la misma manera que el tipo long , y unsigned int de la misma manera que unsigned long .The translation represents type int the same way as type long, and unsigned int the same way as unsigned long.

  • El traductor puede traducir constantes de caracteres a un conjunto de valores de código diferentes del conjunto para el entorno de destino.The translator can translate character constants to a set of code values different from the set for the target environment. Para determinar las propiedades del entorno de destino, use una aplicación compilada para ese entorno para comprobar los valores de los límites. H macros.To determine the properties of the target environment, use an app built for that environment to check the values of the LIMITS.H macros.

  • La expresión no debe consultar el entorno y debe permanecer aislada de los detalles de implementación en el equipo de destino.The expression must not query the environment, and must remain insulated from implementation details on the target computer.

Operadores de preprocesadorPreprocessor operators

definidodefined

El operador de preprocesador definido se puede usar en expresiones constantes especiales, como se muestra en la sintaxis siguiente:The preprocessor operator defined can be used in special constant expressions, as shown by the following syntax:

definido ( identificador )defined( identifier )
defined identificador definidodefined identifier

Esta expresión constante se considera true (distinto de cero) si el identificador está definido actualmente.This constant expression is considered true (nonzero) if the identifier is currently defined. De lo contrario, la condición es false (0).Otherwise, the condition is false (0). Un identificador definido como texto vacío se considera definido.An identifier defined as empty text is considered defined. El operador Defined se puede usar en una #if y una directiva #elif , pero en ningún otro caso.The defined operator can be used in an #if and an #elif directive, but nowhere else.

En el ejemplo siguiente, las directivas #if y #endif controlan la compilación de una de las tres llamadas de función:In the following example, the #if and #endif directives control compilation of one of three function calls:

#if defined(CREDIT)
    credit();
#elif defined(DEBIT)
    debit();
#else
    printerror();
#endif

La llamada de función a credit se compila si el identificador CREDIT está definido.The function call to credit is compiled if the identifier CREDIT is defined. Si el identificador DEBIT está definido, se compila la llamada de función a debit.If the identifier DEBIT is defined, the function call to debit is compiled. Si no está definido ninguno de los identificadores, se compila la llamada a printerror.If neither identifier is defined, the call to printerror is compiled. CREDITY credit son identificadores distintos en C y C++ porque sus casos son diferentes.Both CREDIT and credit are distinct identifiers in C and C++ because their cases are different.

Las instrucciones de compilación condicional del ejemplo siguiente suponen una constante simbólica previamente definida denominada DLEVEL.The conditional compilation statements in the following example assume a previously defined symbolic constant named DLEVEL.

#if DLEVEL > 5
    #define SIGNAL  1
    #if STACKUSE == 1
        #define STACK   200
    #else
        #define STACK   100
    #endif
#else
    #define SIGNAL  0
    #if STACKUSE == 1
        #define STACK   100
    #else
        #define STACK   50
    #endif
#endif
#if DLEVEL == 0
    #define STACK 0
#elif DLEVEL == 1
    #define STACK 100
#elif DLEVEL > 5
    display( debugptr );
#else
    #define STACK 200
#endif

El primer bloque de #if muestra dos conjuntos de directivas anidadas de #if, #elsey #endif .The first #if block shows two sets of nested #if, #else, and #endif directives. El primer conjunto de directivas se procesa solo si DLEVEL > 5 es true.The first set of directives is processed only if DLEVEL > 5 is true. De lo contrario, se procesan las instrucciones después de #else .Otherwise, the statements after #else are processed.

Las directivas #elif y #else del segundo ejemplo se utilizan para tomar una de las cuatro opciones, según el valor de DLEVEL .The #elif and #else directives in the second example are used to make one of four choices, based on the value of DLEVEL. La constante STACK se establece en 0, 100 o 200, según de la definición de DLEVEL.The constant STACK is set to 0, 100, or 200, depending on the definition of DLEVEL. Si DLEVEL es mayor que 5, la instrucciónIf DLEVEL is greater than 5, then the statement

#elif DLEVEL > 5
display(debugptr);

se compila y STACK no está definido.is compiled, and STACK isn't defined.

Un uso común para la compilación condicional es evitar inclusiones múltiples del mismo archivo de encabezado.A common use for conditional compilation is to prevent multiple inclusions of the same header file. En C++, donde las clases suelen definirse en archivos de encabezado, se pueden utilizar construcciones como esta para evitar varias definiciones:In C++, where classes are often defined in header files, constructs like this one can be used to prevent multiple definitions:

/*  EXAMPLE.H - Example header file  */
#if !defined( EXAMPLE_H )
#define EXAMPLE_H

class Example
{
    //...
};

#endif // !defined( EXAMPLE_H )

El código anterior realiza comprobaciones para ver si se define la constante simbólica EXAMPLE_H.The preceding code checks to see if the symbolic constant EXAMPLE_H is defined. Si es así, el archivo ya se ha incluido y no es necesario volver a procesarlo.If so, the file has already been included and doesn't need reprocessing. Si no, se define la constante EXAMPLE_H para marcar EXAMPLE.H como ya procesado.If not, the constant EXAMPLE_H is defined to mark EXAMPLE.H as already processed.

__has_include__has_include

Visual Studio 2017 versión 15,3 y versiones posteriores: determina si un encabezado de biblioteca está disponible para su inclusión:Visual Studio 2017 version 15.3 and later: Determines whether a library header is available for inclusion:

#ifdef __has_include
#  if __has_include(<filesystem>)
#    include <filesystem>
#    define have_filesystem 1
#  elif __has_include(<experimental/filesystem>)
#    include <experimental/filesystem>
#    define have_filesystem 1
#    define experimental_filesystem
#  else
#    define have_filesystem 0
#  endif
#endif

Consulte tambiénSee also

Directivas de preprocesadorPreprocessor directives