Eu quero criar uma matriz estática constante para ser usada em todo o meu arquivo de implementação Objective-C semelhante a algo assim no nível superior do meu arquivo ".m":
static const int NUM_TYPES = 4;
static int types[NUM_TYPES] = {
1,
2,
3,
4 };
Pretendo usar NUM_TYPES
mais tarde no arquivo, então queria colocá-lo em uma variável.
No entanto, quando faço isso, recebo o erro
"'Tipos' modificados de forma variável no escopo do arquivo"
Percebi que isso pode ter algo a ver com o tamanho do array ser uma variável (não recebo esta mensagem quando coloco um literal inteiro lá, como static int types[4]
).
Quero consertar isso, mas talvez esteja fazendo tudo errado ... Tenho 2 objetivos aqui:
- Para ter uma matriz que é acessível em todo o arquivo
- Para encapsular
NUM_TYPES
em uma variável para que eu não tenha o mesmo literal espalhado por diferentes lugares em meu arquivo
Alguma sugestão?
[EDITAR] Encontrado no C Faq: http://c-faq.com/ansi/constasconst.html
#define kNUM_TYPES 4
?@"An NSString literal"
). A única coisa errada com o seu código é que não há necessidade de ponto-e-vírgula.Respostas:
A razão para esse aviso é que const em c não significa constante. Significa "somente leitura". Portanto, o valor é armazenado em um endereço de memória e pode ser potencialmente alterado por código de máquina.
fonte
const
(como lançar longeconst
de um ponteiro e armazenar um valor) é um comportamento indefinido; portanto, o valor de tal objeto é um tempo de compilação ou constante de tempo de execução (dependendo da duração do armazenamento). O valor não pode ser usado em uma expressão constante simplesmente porque o padrão C não diz que pode ser. (A rejeiçãoconst
e o armazenamento de um valor são permitidos se o objeto de destino for definido semconst
ou alocado dinamicamente; literais de string não são,const
mas não podem ser gravados.)extern
constantes em diferentes TUs cujo valor não é conhecido ao compilar a TU atual.Se for usar o pré-processador de qualquer maneira, conforme as outras respostas, você pode fazer o compilador determinar o valor de
NUM_TYPES
automagicamente:#define NUM_TYPES (sizeof types / sizeof types[0]) static int types[] = { 1, 2, 3, 4 };
fonte
sizeof
objetos on como esse é uma constante de tempo de compilação.#define NUM_TYPES 4
fonte
Também é possível usar enumeração.
typedef enum { typeNo1 = 1, typeNo2, typeNo3, typeNo4, NumOfTypes = typeNo4 } TypeOfSomething;
fonte
Como já foi explicado em outras respostas,
const
em C significa apenas que uma variável é somente leitura. Ainda é um valor de tempo de execução. No entanto, você pode usar umenum
como uma constante real em C:enum { NUM_TYPES = 4 }; static int types[NUM_TYPES] = { 1, 2, 3, 4 };
fonte
Na verdade, isso é uma falha em muitos compiladores c. Eu sei que os compiladores com os quais trabalhei não armazenam uma variável "const estática" em um endereço, mas substituem o uso no código pela própria constante. Isso pode ser verificado, pois você obterá a mesma soma de verificação para o código produzido quando usar uma diretiva #define de pré-processador e quando usar uma variável const estática.
De qualquer forma, você deve usar variáveis const estáticas em vez de #defines sempre que possível, pois const estático é seguro para o tipo.
fonte
static const
variável. O comportamento que você está descrevendo pode ser uma otimização válida, mas certamente não é algo que sempre funcionará.