2012-05-24 27 views
16

Estaba escribiendo un código de prueba en C. Por error, inserté un ; después de un #define, que me dio errores. ¿Por qué no se requiere punto y coma para #define s?¿Por qué #define no requiere un punto y coma?

Más específicamente:

Método 1: obras

const int MAX_STRING = 256; 

int main(void) { 
    char buffer[MAX_STRING]; 
} 

Método 2: No funciona - error de compilación.

#define MAX_STRING 256; 

int main(void) { 
    char buffer[MAX_STRING]; 
} 

¿Cuál es la razón del comportamiento diferente de esos códigos? ¿Son esos dos MAX_STRING no constantes?

+35

Retire el; en el método 2 –

+7

Ver la salida del preprocesador y la respuesta será mirarlo a la cara. –

+0

@MichaelFoukarakis, sí, es la forma más fácil 'cpp prog_name.c | cola' decirlo todo. – user51390233

Respuesta

20

#define es una preprocessor directive, no un declaración o declaración como se define por la gramática C (ambos de los que se requieren para terminar con un punto y coma). Las reglas para la sintaxis de cada uno son diferentes.

10

Porque así es como se decidió la sintaxis de las directivas de precompilador .

Sólo declaraciones finales una ; en C/C++, #define es una directiva de pre-procesador y no una declaración.

17

define es una directiva de preprocesador, y es un reemplazo simple, no es una declaración.

Por cierto, como un reemplazo puede contener algo de ; como parte de ella:

// Ugly as hell, but valid 
#define END_STATEMENT ; 

int a = 1 END_STATEMENT // preprocessed to -> int a = 1; 
11

La segunda versión no define una en lo que se refiere a la lengua, sólo una regla de sustitución constante para un bloque de texto. Una vez que el preprocesador ha hecho del trabajo, el compilador ve

char buffer [256;];

que no es sintácticamente válida.

La moraleja de la historia: prefiera la forma const int MAX_STRING = 256; ya que eso lo ayuda a usted, al compilador y al depurador.

+0

No estoy seguro, ¿cómo ayuda el depurador? – saeleko

+3

¿Alguna vez intentó depurar una carga de código con macros? – Bathsheba

+5

En el caso general 'const int MAX_STRING = 256;' es * no * un enfoque viable en lenguaje C, ya que tal 'MAX_STRING' no sería * constante * en C y no se le permitiría usar cuando una expresión constante es necesario. – AnT

38
#define MAX_STRING 256; 

significa:

Cada vez que encuentre MAX_STRING al preprocesar, reemplazarlo con 256;. En su caso, se creará el método 2:

#include <stdio.h> 
#include <stdlib.h> 
#define MAX_STRING 256; 

int main(void) { 
    char buffer [256;]; 
} 

que no es una sintaxis válida.Reemplazar

#define MAX_STRING 256; 

con

#define MAX_STRING 256 

La diferencia entre los dos códigos es que en el primer método se declara una igualdad constante para 256 pero en el segundo código que defina MAX_STRING reposar durante 256; en el archivo de origen .

La directiva #define se utiliza para definir los valores o las macros que utiliza el preprocesador para manipular el código fuente del programa antes de que se compile. Debido a que las definiciones del preprocesador se sustituyen antes de que el compilador actúe sobre el código fuente, cualquier error que introduzca #define es difícil de rastrear.

La sintaxis es la siguiente:

#define CONST_NAME VALUE 

si hay un ; al final, se considera como una parte de VALUE.

para entender cómo es exactamente #define s de trabajo, trate de definir:

#define FOREVER for(;;) 
... 
    FOREVER { 
     /perform something forever. 
    } 

observación interesante por John Hascall:

mayoría de los compiladores le dará una manera de ver la salida después de la fase de preprocesador, este puede ayudar con problemas de depuración como este.

En gcc se puede hacer con la bandera -E.

+5

La mayoría de los compiladores le darán una manera de ver el resultado después de la fase de preprocesador, esto puede ayudar con la depuración de problemas como este. –

13

Ambas constantes? No.

El primer método no produce una constante en lenguaje C. Las variables calificadas por Const no califican como constantes en C. Su primer método funciona solo porque últimos compiladores C99 C admiten matrices de longitud variable (VLA). Su buffer es un VLA en el primer caso específicamente porque MAX_STRING es no una constante. Intente declarar la misma matriz en el alcance del archivo y obtendrá un error, ya que los VLA no están permitidos en el alcance del archivo.

El segundo método se puede usar para asignar nombres a valores constantes en C, pero tiene que hacerlo correctamente. El ; en definición de macro no debería estar allí. Las macros funcionan a través de la sustitución textual y no desea sustituir ese extra ; en su declaración de matriz. La forma correcta para definir esa macro sería

#define MAX_STRING 256 

En lenguaje C, cuando se trata de definir las constantes adecuada nombrados, que son básicamente limitado a macros y enumeraciones. No intente utilizar const "constantes", a menos que realmente sepa que funcionará para sus propósitos.

+0

adicionalmente, los VLA no están permitidos en el alcance del archivo, ya que deben asignarse dinámicamente (stack o 'malloc'). –

1

Esta directiva de preprocesador:

#define MAX_STRING 256; 

le dice al preprocesador para reemplazar todos los MAX_STRING s con 256; - y con el punto y coma. Las instrucciones de preprocesador no necesitan un punto y coma al final. Si coloca uno, el preprocesador realmente piensa que lo dice en serio con un punto y coma.

Si se le confunde con #define s para constantes, const int probablemente sería más fácil de comprender.

Si desea obtener más información sobre cómo utilizar correctamente estas directivas del preprocesador, intente buscar en this website.

Cuestiones relacionadas