"Const estática" vs "#define" vs "enum"

585

¿Cuál es mejor usar entre las siguientes declaraciones en C?

static const int var = 5;

o

#define var 5

o

enum { var = 5 };
Vijay
fuente
35
Curiosamente, esta es casi exactamente la misma pregunta que stackoverflow.com/questions/1637332/static-const-vs-define . La única diferencia es que esa pregunta es sobre C ++, y esta es sobre C. Dado que mi respuesta fue específica de C ++, digo que no los hace idénticos, pero otros pueden estar en desacuerdo.
TED
53
No idéntico, definitivamente. Hay muchas áreas donde C ++ permite la sintaxis de C por razones de compatibilidad. En esos casos, preguntas como "cuál es la mejor manera de hacer X" tendrán diferentes respuestas en C ++. Por ejemplo, inicialización de objeto.
MSalters el
¿Cómo es que esto no se basa en la opinión? Cada uno tiene un propósito diferente
Sam Hammamy
1
@RobertSsupportsMonicaCellio, sí. Gracias por la intimación
Vijay

Respuestas:

690

Depende de para qué necesita el valor. Usted (y todos los demás hasta ahora) omitieron la tercera alternativa:

  1. static const int var = 5;
  2. #define var 5
  3. enum { var = 5 };

Ignorando problemas sobre la elección del nombre, entonces:

  • Si necesita pasar un puntero, debe usar (1).
  • Dado que (2) aparentemente es una opción, no necesita pasar punteros.
  • Ambos (1) y (3) tienen un símbolo en la tabla de símbolos del depurador, lo que facilita la depuración. Es más probable que (2) no tenga un símbolo, dejándote preguntando qué es.
  • (1) no se puede usar como una dimensión para matrices de alcance global; ambos (2) y (3) can.
  • (1) no se puede utilizar como una dimensión para matrices estáticas en el alcance de la función; ambos (2) y (3) can.
  • Bajo C99, todos estos pueden usarse para arreglos locales. Técnicamente, el uso de (1) implicaría el uso de un VLA (matriz de longitud variable), aunque la dimensión referenciada por 'var', por supuesto, se fijaría en el tamaño 5.
  • (1) no se puede usar en lugares como declaraciones de cambio; ambos (2) y (3) can.
  • (1) no se puede usar para inicializar variables estáticas; ambos (2) y (3) can.
  • (2) puede cambiar el código que no quería cambiar porque lo usa el preprocesador; ambos (1) y (3) no tendrán efectos secundarios inesperados como ese.
  • Puede detectar si (2) se ha configurado en el preprocesador; ni (1) ni (3) lo permiten.

Entonces, en la mayoría de los contextos, prefiera la 'enumeración' sobre las alternativas. De lo contrario, es probable que el primer y el último punto sean los factores de control, y debe pensar más si necesita satisfacer ambos a la vez.

Si estuviera preguntando sobre C ++, usaría la opción (1), la constante estática, cada vez.

Jonathan Leffler
fuente
111
lista fantástica! Un inconveniente enumes que se implementan como int([C99] 6.7.2.2/3). A le #definepermite especificar sin signo y largo con Uy Lsufijos, y le constpermite dar un tipo. enumpuede causar problemas con las conversiones de tipo habituales.
Gauthier
37
(2) las personas SIEMPRE se quejan de la seguridad del tipo. Nunca entiendo por qué no solo usas "#define var ((int) 5)" y hurras, tienes seguridad de tipo con una definición.
Ingo Blackman
66
@RedX: tendrías que estar en un entorno muy peculiar para el espacio a una preocupación. Dicho esto, enumni #defineutiliza ni espacio extra, per se. El valor aparecerá en el código del objeto como parte de las instrucciones en lugar de que se le asigne almacenamiento en el segmento de datos o en el montón o en la pila. Tendrá un espacio asignado para el static const int, pero el compilador podría optimizarlo si no toma una dirección.
Jonathan Leffler
15
Otro 'voto' para enums (y static const): no se pueden cambiar. a definepuede ser #undefine'd donde an enumy static constse fijan al valor dado.
Daan Timmer
15
@ QED: No, gracias. Una constante simple es segura fuera del paréntesis. O bien, muéstreme cómo se alteraría un programa que legítimamente podría compilarse al no tener los 5 entre paréntesis. Si fue el argumento de una macro de estilo de función, o si hubo algún operador en la expresión, entonces sería correcto culparme si no hubiera incluido los paréntesis. Pero ese no es el caso aquí.
Jonathan Leffler
282

Generalmente hablando:

static const

Porque respeta el alcance y es de tipo seguro.

La única advertencia que pude ver: si desea que la variable se defina posiblemente en la línea de comando. Todavía hay una alternativa:

#ifdef VAR // Very bad name, not long enough, too general, etc..
  static int const var = VAR;
#else
  static int const var = 5; // default value
#endif

Siempre que sea posible, en lugar de macros / puntos suspensivos, use una alternativa de tipo seguro.

Si realmente NECESITA ir con una macro (por ejemplo, quiere __FILE__o __LINE__), será mejor que nombre su macro MUY cuidadosamente: en su convención de nomenclatura Boost recomienda todo en mayúsculas, comenzando por el nombre del proyecto (aquí BOOST_ ), al examinar la biblioteca, notará que esto es (generalmente) seguido del nombre del área particular (biblioteca) y luego con un nombre significativo.

Generalmente hace nombres largos :)

Matthieu M.
fuente
2
De acuerdo: también con #define existe un peligro general de alterar el código ya que el preprocesador no tiene conocimiento de la sintaxis.
NeilDurant el
10
Es mejor usar #if que #ifdef, pero de lo contrario estoy de acuerdo. +1.
Tim Post
58
Este es el evangelismo estándar de C ++. La respuesta a continuación es MUCHO más clara al explicar cuáles son realmente y qué significan las opciones. En particular: acabo de tener un problema con "const estática". Alguien lo usó para definir alrededor de 2000 "constantes" en un archivo de encabezado. Luego, este archivo de encabezado se incluyó en alrededor de 100 archivos ".c" y ".cpp". => 8Mbytes para "consts". Excelente. Sí, sé que puede usar un vinculador para eliminar consts sin referencia, pero esto todavía le deja a qué "consts" que se hace referencia. Quedarse sin espacio lo que está mal con esta respuesta.
Ingo Blackman
2
@IngoBlackman: Con un buen compilador, solo staticdeben permanecer aquellos cuya dirección esté tomada; y si se toma la dirección, uno no podría haber usado un #defineo enum(sin dirección) ... así que realmente no veo qué alternativa podría haberse usado. Si puede eliminar la "evaluación del tiempo de compilación", podría estar buscando en su extern constlugar.
Matthieu M.
15
@Tim la publicación: #ifpodría ser preferible a #ifdeflas banderas booleanas, pero en este caso se haría imposible definir varcomo 0desde la línea de comandos. Entonces, en este caso, #ifdeftiene más sentido, siempre que 0sea ​​un valor legal para var.
Maarten
108

En C, específicamente? En C la respuesta correcta es: uso #define(o, si corresponde,enum )

Si bien es beneficioso tener las propiedades de alcance y escritura de un constobjeto, en realidadconst objetos en C (a diferencia de C ++) no son constantes verdaderas y, por lo tanto, generalmente son inútiles en la mayoría de los casos prácticos.

Entonces, en C, la elección debe estar determinada por cómo planea usar su constante. Por ejemplo, no puede usar un const intobjeto como caseetiqueta (mientras que una macro funcionará). No puede usar un const intobjeto como un ancho de campo de bits (mientras que una macro funcionará). En C89 / 90 no puede usar un constobjeto para especificar un tamaño de matriz (mientras que una macro funcionará). Incluso en C99 no puede usar un constobjeto para especificar un tamaño de matriz cuando necesita una matriz que no sea VLA .

Si esto es importante para usted, determinará su elección. La mayoría de las veces, no tendrá más remedio que usarlo #defineen C. Y no olvide otra alternativa, que produce constantes verdaderas en C - enum.

En C ++, los constobjetos son constantes verdaderas, por lo que en C ++ casi siempre es mejor preferir la constvariante (sin staticembargo, no es necesario explícito en C ++).

Hormiga
fuente
66
"no se puede usar un objeto const int como etiqueta de caso (mientras que una macro funcionará)" ---> Con respecto a esta declaración probé una variable const int en C en caso de que el conmutador funcione ...
john
8
@john: Bueno, debes proporcionar el código que probaste y nombrar el compilador específico. El uso de const intobjetos en etiquetas de caso es ilegal en todas las versiones del lenguaje C. (Por supuesto, su compilador es gratuito para
admitirlo
11
"... y, por lo tanto, suelen ser inútiles en la mayoría de los casos prácticos ". Estoy en desacuerdo. Son perfectamente útiles siempre que no necesite usar el nombre como una expresión constante. La palabra "constante" en C significa algo que puede evaluarse en tiempo de compilación; constsignifica solo lectura. const int r = rand();Es perfectamente legal.
Keith Thompson
En c ++, es mejor usarlo constexpren comparación con constespecialmente con los stlcontenedores como arrayo bitset.
Mayukh Sarkar
1
@john debes haber probado en una switch()declaración, no en caseuna. También me atraparon en este ☺
Hola-Ángel
32

La diferencia entre static consty #definees que el primero usa la memoria y el segundo no usa la memoria para el almacenamiento. En segundo lugar, no puede pasar la dirección de un #definemientras que puede pasar la dirección de unstatic const . En realidad, dependiendo de las circunstancias en que nos encontremos, debemos seleccionar uno de estos dos. Ambos están en su mejor momento bajo diferentes circunstancias. Por favor, no asuma que uno es mejor que el otro ... :-)

Si ese hubiera sido el caso, Dennis Ritchie habría mantenido el mejor solo ... jajaja ... :-)

envoltura
fuente
66
+1 por mencionar la memoria, algunos sistemas embebidos todavía no tienen mucho, aunque probablemente comenzaría con const estáticos y solo cambiaría a #defines si fuera necesario.
fluffyben
3
Lo acabo de probar. De hecho, const int usa memoria adicional en comparación con #define o enum. Como programamos sistemas embebidos, no podemos permitirnos el uso de memoria adicional. Entonces, volveremos a usar #define o enum.
Davide Andrea
2
Prácticamente hablando, ya no es cierto (a) que a constusa memoria. GCC (probado con 4.5.3 y algunas versiones más nuevas) optimiza fácilmente const inten un literal directo en su código cuando se utiliza -O3. Entonces, si realiza un desarrollo embebido con poca RAM (por ejemplo, AVR), puede usar con seguridad C consts si usa GCC u otro compilador compatible. No lo he probado, pero espero que Clang haga lo mismo por cierto.
Raphael
19

En C #definees mucho más popular. Puede usar esos valores para declarar tamaños de matriz, por ejemplo:

#define MAXLEN 5

void foo(void) {
   int bar[MAXLEN];
}

ANSI C no le permite usar static consts en este contexto hasta donde yo sé. En C ++ debe evitar las macros en estos casos. Puedes escribir

const int maxlen = 5;

void foo() {
   int bar[maxlen];
}

e incluso dejar de lado staticporque el enlace interno ya está implícito const[solo en C ++].

sellibitze
fuente
1
¿Qué quieres decir con "enlace interno"? Puedo tener const int MY_CONSTANT = 5;en un archivo y acceder a él extern const int MY_CONSTANT;en otro. No pude encontrar ninguna información en el estándar (al menos C99) sobre cómo constcambiar el comportamiento predeterminado "6.2.2: 5 Si la declaración de un identificador para un objeto tiene un alcance de archivo y ningún especificador de clase de almacenamiento, su enlace es externo".
Gauthier
@Gauthier: Lo siento, por eso. Debería haber dicho "está implícito por const ya en el lenguaje C ++". Esto es específico de C ++.
sellibitze
@sellibitze es bueno ver algunos argumentos en el camino en lugar de toneladas de OPINIÓN. Si hubiera una bonificación por argumentos verdaderos, ¡lo tienes!
Paul
1
A partir de C99, su segundo fragmento es legal. bares un VLA (matriz de longitud variable); Es probable que el compilador genere código como si su longitud fuera constante.
Keith Thompson
14

Otro inconveniente de consten C es que no puede usar el valor para inicializar otro const.

static int const NUMBER_OF_FINGERS_PER_HAND = 5;
static int const NUMBER_OF_HANDS = 2;

// initializer element is not constant, this does not work.
static int const NUMBER_OF_FINGERS = NUMBER_OF_FINGERS_PER_HAND 
                                     * NUMBER_OF_HANDS;

Incluso esto no funciona con una constante, ya que el compilador no lo ve como una constante:

static uint8_t const ARRAY_SIZE = 16;
static int8_t const lookup_table[ARRAY_SIZE] = {
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; // ARRAY_SIZE not a constant!

Me encantaría usar mecanografiado consten estos casos, de lo contrario ...

Gauthier
fuente
55
Un poco tarde para el juego, pero esta pregunta surgió en otra pregunta. Perseguir por qué static uint8_t const ARRAY_SIZE = 16;de repente ya no compila puede ser un poco desafiante, especialmente cuando #define ARRAY_SIZE 256está enterrado a diez capas de profundidad en una red enmarañada de encabezados. Ese nombre en mayúsculas ARRAY_SIZEestá pidiendo problemas. Reserve ALL_CAPS para macros y nunca defina una macro que no esté en forma ALL_CAPS.
David Hammen
@David: buenos consejos, que seguiré.
Gauthier
1
4 años después me ahorraste mucho tiempo pensando por qué no podía "anidar" const. ¡Esto podría ser votado más!
Plouff
11

Si puede salirse con la suya, static consttiene muchas ventajas. Obedece a los principios del alcance normal, es visible en un depurador y generalmente obedece las reglas que obedecen las variables.

Sin embargo, al menos en el estándar C original, en realidad no es una constante. Si lo usa #define var 5, puede escribir int foo[var];como una declaración, pero no puede hacerlo (excepto como una extensión del compilador "con static const int var = 5;. Este no es el caso en C ++, donde la static constversión se puede usar en cualquier lugar que la #defineversión pueda, y creo que esto Es también el caso de C99.

Sin embargo, nunca nombre una #defineconstante con un nombre en minúscula. Anulará cualquier posible uso de ese nombre hasta el final de la unidad de traducción. Las constantes macro deberían estar en lo que efectivamente es su propio espacio de nombres, que tradicionalmente son todas letras mayúsculas, quizás con un prefijo.

David Thornley
fuente
66
Desafortunadamente, este no es el caso con C99. consten C99 todavía no es una constante real. Puede declarar el tamaño de la matriz con a consten C99, pero solo porque C99 admite matrices de longitud variable. Por esta razón, solo funcionará donde se permitan los VLA. Por ejemplo, incluso en C99, aún no puede usar a constpara declarar el tamaño de una matriz de miembros en a struct.
ANT
Si bien es cierto que C99 no le permitirá hacer eso, GCC (probado con 4.5.3) le permitirá inicializar perfectamente matrices con un const inttamaño como si fuera una constante C ++ o una macro. Si desea depender de esta desviación de GCC del estándar, por supuesto, es su elección, yo personalmente iría con él a menos que realmente pueda evitar usar otro compilador que GCC o Clang, este último tiene la misma característica aquí (probado con Clang 3.7)
Raphael
7

SIEMPRE es preferible usar const, en lugar de #define. Eso es porque const es tratado por el compilador y #define por el preprocesador. Es como si #definir en sí mismo no formara parte del código (más o menos).

Ejemplo:

#define PI 3.1416

El nombre simbólico PI nunca puede ser visto por los compiladores; puede ser eliminado por el preprocesador incluso antes de que el código fuente llegue a un compilador. Como resultado, es posible que el nombre PI no se ingrese en la tabla de símbolos. Esto puede ser confuso si obtiene un error durante la compilación que implica el uso de la constante, porque el mensaje de error puede referirse a 3.1416, no a PI. Si PI se definiera en un archivo de encabezado que no escribió, no tendría idea de dónde vino ese 3.1416.

Este problema también puede surgir en un depurador simbólico, porque, nuevamente, el nombre con el que está programando puede no estar en la tabla de símbolos.

Solución:

const double PI = 3.1416; //or static const...
suren
fuente
6

#define var 5te causará problemas si tienes cosas como mystruct.var.

Por ejemplo,

struct mystruct {
    int var;
};

#define var 5

int main() {
    struct mystruct foo;
    foo.var = 1;
    return 0;
}

El preprocesador lo reemplazará y el código no se compilará. Por esta razón, el estilo de codificación tradicional sugiere que todas las constantes #defineusan letras mayúsculas para evitar conflictos.

Interrupción no enmascarable
fuente
6

Escribí un programa de prueba rápida para demostrar una diferencia:

#include <stdio.h>

enum {ENUM_DEFINED=16};
enum {ENUM_DEFINED=32};

#define DEFINED_DEFINED 16
#define DEFINED_DEFINED 32

int main(int argc, char *argv[]) {

   printf("%d, %d\n", DEFINED_DEFINED, ENUM_DEFINED);

   return(0);
}

Esto compila con estos errores y advertencias:

main.c:6:7: error: redefinition of enumerator 'ENUM_DEFINED'
enum {ENUM_DEFINED=32};
      ^
main.c:5:7: note: previous definition is here
enum {ENUM_DEFINED=16};
      ^
main.c:9:9: warning: 'DEFINED_DEFINED' macro redefined [-Wmacro-redefined]
#define DEFINED_DEFINED 32
        ^
main.c:8:9: note: previous definition is here
#define DEFINED_DEFINED 16
        ^

Tenga en cuenta que enum da un error cuando define da una advertencia.

Michael Potter
fuente
4

La definición

const int const_value = 5;

no siempre define un valor constante. Algunos compiladores (por ejemplo, tcc 0.9.26 ) simplemente asignan memoria identificada con el nombre "const_value". Usando el identificador "const_value" no puede modificar esta memoria. Pero aún podría modificar la memoria utilizando otro identificador:

const int const_value = 5;
int *mutable_value = (int*) &const_value;
*mutable_value = 3;
printf("%i", const_value); // The output may be 5 or 3, depending on the compiler.

Esto significa la definición

#define CONST_VALUE 5

es la única forma de definir un valor constante que no puede modificarse de ninguna manera.

usuario2229691
fuente
8
Modificar un valor constante usando un puntero es un comportamiento indefinido. Si estás dispuesto a ir allí, #definetambién puedes modificarlo editando el código de la máquina.
ugoren
En parte tienes razón. Probé el código con Visual Studio 2012 y se imprime 5. Pero no se puede modificar #defineporque es una macro de preprocesador. No existe en el programa binario. Si uno quería modificar todos los lugares donde CONST_VALUEse usaba, tenía que hacerlo uno por uno.
user2229691
3
@ugoren: Supongamos que escribe #define CONST 5, entonces if (CONST == 5) { do_this(); } else { do_that(); }, y el compilador elimina la elserama. ¿Cómo propone editar el código de la máquina para cambiar CONSTa 6?
Keith Thompson
@KeithThompson, nunca dije que se puede hacer de manera fácil y confiable. Eso #defineno es a prueba de balas.
ugoren
3
@ugoren: Mi punto es que "editar el código de la máquina" no es una forma sensata de duplicar el efecto de cambiar el valor de a #define. La única forma real de hacerlo es editar el código fuente y volver a compilar.
Keith Thompson
4

Aunque la pregunta era sobre enteros, vale la pena señalar que #define y las enumeraciones son inútiles si necesita una estructura o cadena constante. Ambos se pasan generalmente a funciones como punteros. (Con cadenas es necesario; con estructuras es mucho más eficiente).

En cuanto a los enteros, si está en un entorno incrustado con memoria muy limitada, es posible que deba preocuparse sobre dónde se almacena la constante y cómo se compilan los accesos a ella. El compilador puede agregar dos consts en tiempo de ejecución, pero agrega dos #defines en tiempo de compilación. Una constante #define puede convertirse en una o más instrucciones MOV [inmediatas], lo que significa que la constante se almacena efectivamente en la memoria del programa. Una constante constante se almacenará en la sección .const en la memoria de datos. En sistemas con una arquitectura de Harvard, podría haber diferencias en el rendimiento y el uso de la memoria, aunque probablemente serían pequeños. Pueden ser importantes para la optimización de núcleo duro de los bucles internos.

Adam Haun
fuente
3

No creo que haya una respuesta para "lo que siempre es mejor" pero, como dijo Matthieu

static const

Es de tipo seguro. Sin #defineembargo, mi mayor motivo de molestia es cuando al depurar en Visual Studio no se puede ver la variable. Da un error que el símbolo no se puede encontrar.

Afcrowe
fuente
1
"no puedes ver la variable" Correcto, no es una variable. No cambia, ¿por qué necesitas verlo? Puede encontrar en todas partes donde se usa simplemente buscando la etiqueta. ¿Por qué necesitarías (o incluso querrías) ver un #define?
Marshall Eubanks
3

Por cierto, una alternativa a #define, que proporciona un alcance adecuado pero se comporta como una constante "real", es "enum". Por ejemplo:

enum {number_ten = 10;}

En muchos casos, es útil definir tipos enumerados y crear variables de esos tipos; si eso se hace, los depuradores pueden mostrar variables de acuerdo con su nombre de enumeración.

Sin embargo, una advertencia importante para hacerlo: en C ++, los tipos enumerados tienen compatibilidad limitada con los enteros. Por ejemplo, por defecto, uno no puede realizar operaciones aritméticas sobre ellos. Me parece un comportamiento curioso por defecto para las enumeraciones; si bien hubiera sido bueno tener un tipo "enum estricto", dado el deseo de tener C ++ generalmente compatible con C, creo que el comportamiento predeterminado de un tipo "enum" debería ser intercambiable con enteros.

Super gato
fuente
1
En C, las constantes de enumeración son siempre de tipo int, por lo que el "enum hack" no se puede usar con otros tipos enteros. (El tipo de enumeración es compatible con algún tipo de entero definido por la implementación, no necesariamente int, pero en este caso el tipo es anónimo, por lo que no importa)
Keith Thompson,
@KeithThompson: desde que escribí lo anterior, he leído que MISRA-C emitirá un chillido si un compilador asigna un tipo diferente inta una variable de enumeración (que los compiladores pueden hacer) y uno intenta asignar a dicha variable un miembro de su propia enumeración. Deseo que los comités de normas agreguen formas portátiles de declarar tipos enteros con semántica especificada. CUALQUIER plataforma, independientemente de su chartamaño, debería poder, por ejemplo, declarar un tipo que envolverá el mod 65536, incluso si el compilador tiene que agregar muchas AND R0,#0xFFFFo instrucciones equivalentes.
supercat
Puede usar uint16_t, aunque, por supuesto, ese no es un tipo de enumeración. Sería bueno permitir que el usuario especifique el tipo de entero usado para representar un tipo de enumeración dado, pero puede lograr el mismo efecto con un typedeffor uint16_ty una serie de #defines para valores individuales.
Keith Thompson
1
@KeithThompson: entiendo que por razones históricas, estamos atrapados con el hecho de que algunas plataformas evaluarán 2U < -1Lcomo verdaderas y otras como falsas, y ahora estamos atrapados con el hecho de que algunas plataformas implementarán una comparación entre uint32_ty int32_tcomo se firmó y algunos como sin firmar, pero eso no significa que el Comité no pueda definir un sucesor de C compatible hacia arriba que incluya tipos cuya semántica sea coherente en todos los compiladores.
supercat
1

Una simple diferencia:

En el tiempo de preprocesamiento, la constante se reemplaza por su valor. Por lo tanto, no puede aplicar el operador de referencia a una definición, pero puede aplicar el operador de referencia a una variable.

Como es de suponer, definir es más rápido que la constante estática.

Por ejemplo, tener:

#define mymax 100

No puedes hacer printf("address of constant is %p",&mymax);.

Pero teniendo

const int mymax_var=100

que puede hacer printf("address of constant is %p",&mymax_var);.

Para ser más claro, la definición se reemplaza por su valor en la etapa de preprocesamiento, por lo que no tenemos ninguna variable almacenada en el programa. Solo tenemos el código del segmento de texto del programa donde se utilizó la definición.

Sin embargo, para const estática tenemos una variable que se asigna en algún lugar. Para gcc, las constantes estáticas se asignan en el segmento de texto del programa.

Arriba, quería contar sobre el operador de referencia, así que reemplace la desreferencia con referencia.

mihaitzateo
fuente
1
Tu respuesta es muy incorrecta. Esto se trata de C, su respuesta se relaciona con C ++, que tiene una semántica muy diferente para el constcalificador. C no tiene constantes simbólicas que no sean constantes enum . A const intes una variable. También confunde el lenguaje y las implementaciones específicas. No hay ningún requisito sobre dónde colocar el objeto. Y ni siquiera es cierto para gcc: generalmente coloca constvariables calificadas en la .rodatasección. Pero eso depende de la plataforma de destino. Y te refieres a la dirección del operador &.
Demasiado honesto para este sitio
0

Observamos el código de ensamblador producido en el MBF16X ... Ambas variantes dan como resultado el mismo código para operaciones aritméticas (ADD Inmediato, por ejemplo).

Por const intlo tanto, se prefiere para la verificación de tipo, mientras que #definees de estilo antiguo. Tal vez es específico del compilador. Así que verifique su código de ensamblador producido.

invitado
fuente
-1

No estoy seguro de tener razón, pero en mi opinión, llamar al #definevalor d es mucho más rápido que llamar a cualquier otra variable normalmente declarada (o valor constante). Es porque cuando el programa se está ejecutando y necesita usar alguna variable normalmente declarada, necesita saltar al lugar exacto en la memoria para obtener esa variable.

Al contrario, cuando usa el #definevalor d, el programa no necesita saltar a ninguna memoria asignada, solo toma el valor. Si #define myValue 7y el programa llama myValue, se comporta exactamente igual que cuando solo llama 7.

pajczur
fuente