objective-c const c-preprocessor

objective c - #define vs const en Objective-C



c-preprocessor (6)

Primero, descubrí que no es posible definir el tipo de constante usando #define, ¿por qué?

¿Por qué es qué? No es verdad:

#define MY_INT_CONSTANT ((int) 12345)

En segundo lugar, ¿hay ventajas de usar uno de ellos sobre el otro?

Sí. #define define una macro que se reemplaza incluso antes de que comience la compilación. const simplemente modifica una variable para que el compilador señale un error si intentas cambiarla. Hay contextos en los que puedes usar un #define pero no puedes usar un const (aunque estoy luchando por encontrar uno usando el último clang). En teoría, una const ocupa espacio en el ejecutable y requiere una referencia a la memoria, pero en la práctica esto es insignificante y puede ser optimizado por el compilador.

const son mucho más amigables con el compilador y el depurador que #define s. En la mayoría de los casos, este es el punto principal que debe considerar al tomar una decisión sobre cuál usar.

Solo pensé en un contexto en el que puedes usar #define pero no const . Si tiene una constante que desea usar en muchos archivos .c , con un #define , simplemente póngalo en un encabezado. const , tienes que tener una definición en un archivo C y

// in a C file const int MY_INT_CONST = 12345; // in a header extern const int MY_INT_CONST;

en un encabezado. MY_INT_CONST no se puede usar como el tamaño de una matriz de alcance estático o global en ningún archivo C, excepto en el que está definido.

Sin embargo, para las constantes enteras puede usar una enum . De hecho, eso es lo que Apple hace casi invariablemente. Esto tiene todas las ventajas de #define s y const s pero solo funciona para constantes enteras.

// In a header enum { MY_INT_CONST = 12345, };

Finalmente, ¿qué camino es más eficiente y / o más seguro?

#define es más eficiente en teoría aunque, como dije, los compiladores modernos probablemente aseguran que hay poca diferencia. #define es más seguro ya que siempre es un error del compilador intentar asignarlo

#define FOO 5 // .... FOO = 6; // Always a syntax error

const s puede ser engañado para que se le asigne aunque el compilador pueda emitir advertencias:

const int FOO = 5; // ... (int) FOO = 6; // Can make this compile

Dependiendo de la plataforma, la asignación aún puede fallar en el tiempo de ejecución si la constante se coloca en un segmento de solo lectura y su comportamiento oficialmente indefinido de acuerdo con el estándar de C.

Personalmente, para constantes enteras, siempre uso enum s para constantes de otros tipos, utilizo const menos que tenga una muy buena razón para no hacerlo.

Soy nuevo en Objective-C, y tengo algunas preguntas sobre const y la directiva de preprocesamiento #define .

Primero, descubrí que no es posible definir el tipo de constante usando #define . ¿Porqué es eso?

En segundo lugar, ¿hay ventajas de usar uno de ellos sobre el otro?

Finalmente, ¿qué camino es más eficiente y / o más seguro?


Además de los comentarios de otras personas, los errores que usan #define son difíciles de depurar cuando el pre-procesador los agarra antes del compilador.


Dado que las directivas del preprocesador no se respetan, sugiero usar una const . No puede especificar un tipo con un preprocesador porque una directiva de preprocesador se resuelve antes de la compilación. Bueno, puedes, pero algo así como:

#define DEFINE_INT(name,value) const int name = value;

y usarlo como

DEFINE_INT(x,42)

que sería visto por el compilador como

const int x = 42;

Primero, descubrí que no es posible definir el tipo de constante usando #define, ¿por qué?

Puedes ver mi primer fragmento.

En segundo lugar, ¿hay ventajas de usar uno de ellos sobre el otro?

Generalmente tener una directiva const lugar de una preprocesadora ayuda a la depuración, no tanto en este caso (pero aún lo hace).

Finalmente, ¿qué camino es más eficiente y / o más seguro?

Ambos son tan eficientes. Yo diría que la macro puede ser potencialmente más segura ya que no se puede cambiar durante el tiempo de ejecución, mientras que una variable podría.


De un codificador C:

Un const es simplemente una variable cuyo contenido no se puede cambiar.

#define name value , sin embargo, es un comando preprocesador que reemplaza todas las instancias del name con value .

Por ejemplo, si #define defTest 5 , todas las instancias de defTest en su código serán reemplazadas por 5 cuando compile.


Es importante entender la diferencia entre las instrucciones #define y const que no están pensadas para las mismas cosas.

const

const se usa para generar un objeto del tipo solicitado que será, una vez inicializado, constante. Significa que es un objeto en la memoria del programa y puede usarse como de solo lectura. El objeto se genera cada vez que se inicia el programa.

#define

#define se usa para facilitar la legibilidad del código y las modificaciones futuras. Al usar un definir, solo enmascara un valor detrás de un nombre. Por lo tanto, al trabajar con un rectángulo puede definir ancho y alto con los valores correspondientes. Luego, en el código, será más fácil de leer ya que en lugar de números habrá nombres.

Si luego decide cambiar el valor del ancho, solo tendrá que cambiarlo en la definición en lugar de un hallazgo / reemplazo aburrido y peligroso en su archivo completo. Al compilar, el preprocesador reemplazará todo el nombre definido por los valores en el código. Por lo tanto, no hay tiempo perdido usándolos.


He usado #define antes para ayudar a crear más métodos de un método, como si tuviera algo así.

// This method takes up to 4 numbers, we don''t care what the method does with these numbers. void doSomeCalculationWithMultipleNumbers:(NSNumber *)num1 Number2:(NSNumber *)num2 Number3:(NSNumber *)num23 Number3:(NSNumber *)num3;

Pero también tengo que tener un método que solo tome 3 números y 2 números, así que en lugar de escribir dos métodos nuevos, voy a usar el mismo usando #define, como tal.

#define doCalculationWithFourNumbers(num1, num2, num3, num4) / doSomeCalculationWithMultipleNumbers((num1), (num2), (num3), (num4)) #define doCalculationWithThreeNumbers(num1, num2, num3) / doSomeCalculationWithMultipleNumbers((num1), (num2), (num3), nil) #define doCalculationWithTwoNumbers(num1, num2) / doSomeCalculationWithMultipleNumbers((num1), (num2), nil, nil)

Creo que es algo muy bueno, sé que puedes ir directamente al método y simplemente ponerlo en los espacios que no quieres, pero si estás construyendo una biblioteca, es muy útil. También así es como

NSLocalizedString(<#key#>, <#comment#>) NSLocalizedStringFromTable(<#key#>, <#tbl#>, <#comment#>) NSLocalizedStringFromTableInBundle(<#key#>, <#tbl#>, <#bundle#>, <#comment#>)

están hechos.

Mientras que no creo que puedas hacer esto con constantes. Pero las constantes tienen beneficios sobre #define como que no puede especificar un tipo con un #define porque es una directiva de preprocesador que se resuelve antes de la compilación, y si obtiene un error con #define son más difíciles de depurar que constantes. Ambos tienen ventajas y desventajas, pero yo diría que todo depende del programador al que decidiste utilizar. He escrito una biblioteca con ambos al usar #define para hacer lo que he mostrado y constantes para declarar variables constantes en las que necesito especificar un tipo.