Quiero crear una matriz estática constante para usar en todo mi archivo de implementación de Objective-C similar a algo como esto en el nivel superior de mi archivo ".m":
static const int NUM_TYPES = 4;
static int types[NUM_TYPES] = {
1,
2,
3,
4 };
Planeo usarlo NUM_TYPES
más adelante en el archivo, así que quería ponerlo en una variable.
Sin embargo, cuando hago esto, aparece el error
"'Tipos' modificados de forma variable en el ámbito del archivo"
Entiendo que esto puede tener algo que ver con que el tamaño de la matriz sea una variable (no recibo este mensaje cuando pongo un literal entero allí, como static int types[4]
).
Quiero arreglar esto, pero tal vez lo esté haciendo mal ... Tengo 2 objetivos aquí:
- Tener una matriz accesible en todo el archivo
- Para encapsular
NUM_TYPES
en una variable para que no tenga el mismo literal disperso en diferentes lugares en mi archivo
¿Alguna sugerencia?
[EDITAR] Encontré esto en C Faq: http://c-faq.com/ansi/constasconst.html
#define kNUM_TYPES 4
?@"An NSString literal"
). El único problema con su fragmento de código es que no es necesario el punto y coma.Respuestas:
El motivo de esta advertencia es que const en c no significa constante. Significa "solo lectura". Por lo tanto, el valor se almacena en una dirección de memoria y podría modificarse potencialmente mediante el código de la máquina.
fuente
const
(por ejemplo, alejandoconst
un puntero y almacenando un valor) es un comportamiento indefinido; por lo tanto, el valor de dicho objeto es una constante de tiempo de compilación o de tiempo de ejecución (dependiendo de la duración del almacenamiento). El valor no se puede usar en una expresión constante simplemente porque el estándar C no dice que pueda serlo. (Reparto de distanciaconst
y el almacenamiento de un valor se permite si el objeto de destino se define sinconst
o dinámicamente asignada; literales de cadena no estánconst
, pero no pueden ser escritos a.)extern
constantes en diferentes TU cuyo valor no se conoce al compilar la TU actual.Si va a usar el preprocesador de todos modos, según las otras respuestas, puede hacer que el compilador determine el valor de
NUM_TYPES
automágicamente:#define NUM_TYPES (sizeof types / sizeof types[0]) static int types[] = { 1, 2, 3, 4 };
fuente
sizeof
en objetos como ese es una constante en tiempo de compilación.#define NUM_TYPES 4
fuente
También es posible utilizar la enumeración.
typedef enum { typeNo1 = 1, typeNo2, typeNo3, typeNo4, NumOfTypes = typeNo4 } TypeOfSomething;
fuente
Como ya se explicó en otras respuestas,
const
en C simplemente significa que una variable es de solo lectura. Sigue siendo un valor en tiempo de ejecución. Sin embargo, puede usar anenum
como una constante real en C:enum { NUM_TYPES = 4 }; static int types[NUM_TYPES] = { 1, 2, 3, 4 };
fuente
En mi humilde opinión, esto es un defecto en muchos compiladores de c. Sé a ciencia cierta que los compiladores con los que trabajé no almacenan una variable "const estática" en una dirección, sino que reemplazan el uso en el código por la constante. Esto se puede verificar, ya que obtendrá la misma suma de comprobación para el código producido cuando use una directiva #define de preprocesadores y cuando use una variable estática const.
De cualquier manera, debe usar variables estáticas const en lugar de #defines siempre que sea posible, ya que la constante estática es segura para los tipos.
fuente
static const
variable. El comportamiento que está describiendo puede ser una optimización válida, pero ciertamente no es algo que siempre funcione.