estoy algo confundido por #define
declaraciones. En las bibliotecas, parecen ser un medio de comunicación entre diferentes archivos, con muchos #ifdef
arena #ifndef
s.
Habiendo dicho eso, ahora tengo dos archivos. file1.c
y file2.c
compilado junto con #define TEST 10
en el interior file2.c
. Sin embargo, cuando uso TEST
en el interior file2.c
el compilador da el siguiente mensaje de error:
'TEST' undeclared (first use in this function)
Son #define
directivas globales?
#define
s no son globales, son solo una sustitución donde sea que se usen (si se declaran en la misma unidad de compilación)
Están no globales, son no símbolos, son irrelevante en la vinculación, solo son relevantes en pre-compilación.
-
¿Qué quiere decir con “unidad de compilación”? como puedo tener
file1.c
yfile.2
en la misma unidad de compilación?– azul aleatorio
9 de mayo de 2012 a las 9:09
-
No. Se recopilan por separado. y gallina unidas entre sí. ¿Estás familiarizado con el proceso de compilación de C?
– MByD
9 de mayo de 2012 a las 9:12
-
Asi que
file1.c
yfile2.c
nunca puede estar en la misma unidad de compilación?– azul aleatorio
9 mayo 2012 a las 10:00
-
básicamente – no. si desea compartir una macro entre ellos, colóquela en un archivo de encabezado e incluya ese encabezado en ambos archivos.
– MByD
9 de mayo de 2012 a las 10:02
-
@Randomblue: Piense en una “unidad de compilación” como “archivo ac, y todos los encabezados que incluye, y todos los encabezados que incluyen, etc., etc., etc., hasta que no haya más encabezados”. Este es un “fragmento” que compila el compilador. Después de que el compilador compila cada archivo c por separado, vincula esos resultados entre sí.
– Pato mugido
25/04/2017 a las 21:44
jamesdlin
#define
Las macros d son globales en el sentido de que no siguen las reglas normales de alcance de C. La sustitución textual de la macro se aplicará (casi) en cualquier sitio el nombre de la macro aparece después de su #define
. (Las excepciones notables son si el nombre de la macro es parte de un comentario o parte de un literal de cadena).
Si define una macro en un archivo de encabezado, cualquier archivo que #include
s ese archivo de encabezado heredará esa macro (ya sea que se desee o no), a menos que el archivo la anule explícitamente después con #undef
.
En tu ejemplo, file2.c
no sabe sobre el TEST
macro. ¿Cómo sabría recoger el #define
de file1.c
? ¿Por magia? Dado que las macros realizan la sustitución textual en el código fuente, no hay representación de ellas en los archivos de objetos generados. file2.c
por lo tanto, necesita saber esa regla de sustitución en sí misma, y si desea que se comparta en varios archivos, eso #define
necesita vivir en un archivo de encabezado común que su .c
archivos #include
.
Si está preguntando específicamente cuántos de los #ifdef
s que ve en el trabajo de las bibliotecas, es probable que muchos de ellos se comparen con predefinido nombres de macro proporcionados por el entorno de compilación. Por ejemplo, un compilador C99 define un __STDC_VERSION__
macro que especifica la versión del idioma; un compilador de Microsoft define un _MSC_VER
macro. (A menudo, estas macros predefinidas comienzan con guiones bajos iniciales, ya que esos nombres están reservados para el compilador).
Además, la mayoría de los compiladores permiten definir macros simples como argumentos de línea de comandos. Por ejemplo, puede compilar su código a través de gcc -DNDEBUG file1.c
compilar file.c
con NDEBUG
definido para deshabilitar assert
s.
-
Gracias por información útil
– usuario5066707
25 de abril de 2017 a las 21:02
Por si alguien lee esto más tarde, y para añadir alguna información práctica:
- Algunos entornos, como atmel, vs o iar, le permiten definir directivas #define globales. Básicamente pasan estos valores definidos al precompilador en algún formato de línea de comandos.
- Puede hacer lo mismo en comandos por lotes o archivos MAKE, etc.
- Arduino siempre agrega una variante de placa (generalmente ubicada en hardware\arduino\variants) a todas las compilaciones. En ese momento, puede crear un nuevo tablero que contenga sus directivas de definición global y usarlo de esa manera. Por ejemplo, puede definir una placa mega2560 (depuración) a partir de la mega2560 original que contiene algunas directivas de depuración. Agregará una referencia a esa variante en “boards.txt”, copiando y pegando algún texto y modificándolo correctamente.
Al final del día, tendrá que dar ese hfile global o directiva global al compilador de una forma u otra.
Depende de donde se definan.
– Nick
9 de mayo de 2012 a las 9:01
#define
es una directiva de preprocesador, solo hace sustituciones de texto simples en tiempo de compilación, solo la unidad de compilación y cualquier#include
los archivos d ver a#define
.– Pablo R.
9 de mayo de 2012 a las 9:02