Definindo valores const em C

votos
4

Eu tenho um projeto C, onde todo o código está organizado em *.c/ *.hpares de arquivo e eu preciso definir um valor constante em um arquivo, que será no entanto também ser utilizado em outros arquivos. Como devo declarar e definir este valor?

Deve ser como static const ...no *.harquivo? Como extern const ...no *.harquivo e definido no *.carquivo? De que maneira isso importa se o valor não é um tipo de dados primitivo ( int, double, etc), mas um char *ou um struct? (Embora, no meu caso, é uma double.)

Definindo coisas dentro *.harquivos não parece ser uma boa idéia em geral; deve-se declarar as coisas no *.harquivo, mas defini-los no *.carquivo. No entanto, a extern const ...abordagem parece ineficiente, como o compilador não seria capaz para inline o valor, em vez de ter para ser acessado através do seu endereço o tempo todo.

Eu acho que a essência desta questão é: Se um definir static const ...valores em *.harquivos em C, a fim de usá-los em mais de um lugar?

Publicado 10/12/2008 em 07:16
fonte usuário
Em outras línguas...                            


10 respostas

votos
8

A regra que eu sigo é a declarar apenas coisas em arquivos H e defini-los em arquivos C. Você pode declarar e definir em um único arquivo C, assumindo que só serão utilizadas nesse arquivo.

Por declaração, quero dizer notificar o compilador de sua existência, mas não alocar espaço para ele. Isto inclui #define, typedef, extern int x, e assim por diante.

Definições atribuir valores às declarações e alocar espaço para eles, tais como int xe const int x. Isso inclui definições de funções; incluindo estes em arquivos de cabeçalho freqüentemente levam ao espaço código desperdiçado.

Já vi muitos programadores júnior ficar confuso quando eles colocaram const int x = 7;em um arquivo de cabeçalho e depois perguntam por que eles obter um erro de link para xser definido mais de uma vez. Eu acho que em um mínimo, seria necessário static const int x, de modo a evitar este problema.

Eu não seria muito preocupado com a velocidade do código. O principal problema com computadores (em termos de velocidade e custo) há muito tempo mudou de velocidade de execução à facilidade de desenvolvimento.

Respondeu 10/12/2008 em 07:46
fonte usuário

votos
3

Se você precisa de constantes (real, compilar constantes de tempo) você pode fazer isso de três maneiras, colocando-os em arquivos de cabeçalho (não há nada de mal com isso):

enum {
    FOO_SIZE = 1234,
    BAR_SIZE = 5678
};

#define FOO_SIZE 1234
#define BAR_SIZE 5678

static const int FOO_SIZE = 1234;
static const int BAR_SIZE = 5678;

Em C ++, eu tendem a usar o caminho enumeração, uma vez que pode ser com escopo em um namespace. Para C, eu uso o macro. Este basicially se resume a uma questão de gosto embora. Se você precisa de constantes ponto flutuante, você não pode mais usar a enumeração. Em C ++ eu uso a última forma, o static const double, nesse caso (nota na estática C ++ seria redundante seguida, eles se tornaria estática automaticamente uma vez que são const). Em C, eu gostaria de continuar usando as macros.

É um mito que usar o terceiro método vai abrandar o seu programa de forma alguma. Eu prefiro a enumeração já que os valores que você tem são rvalues - você não pode obter o seu endereço, o que eu considero como uma segurança adicional. Além disso, há muito menos código caldeira de placa escrita. O olho é concentrada nas constantes.

Respondeu 11/12/2008 em 00:14
fonte usuário

votos
1

Como regra geral, você não definir as coisas como staticem um cabeçalho. Se você fizer definir staticvariáveis em um cabeçalho, cada arquivo que usa o cabeçalho obtém sua própria cópia privada de tudo o que é declarado static, que é a antítese do DRY princípio: não repetir-se .

Então, você deve usar uma alternativa. Para tipos inteiros, usando enum (definido no cabeçalho) é muito potente; ele funciona bem com os depuradores também (embora os melhores depuradores pode ser capaz de ajudar com #definevalores de macro também). Para os tipos de números não inteiros, uma externdeclaração (opcionalmente com qualificado const) no cabeçalho e uma única definição em um arquivo C é geralmente o melhor caminho a percorrer.

Respondeu 10/12/2008 em 08:53
fonte usuário

votos
1

Você realmente tem uma necessidade de se preocupar com a vantagem de linha? A menos que você está escrevendo código incorporado, para manter a legibilidade. Se ele é realmente um número mágico de alguma coisa, eu usaria um definir; Eu acho que const é melhor para coisas como strings de versão const e modificar os argumentos de chamada de função. Dito isto, a definir em .c, declarar por .h regra é definitivamente uma convenção bastante universalmente aceito, e eu não iria quebrá-lo só porque você pode salvar uma pesquisa de memória.

Respondeu 10/12/2008 em 08:28
fonte usuário

votos
0

Em C ++, você deve sempre usar

const int SOME_CONST = 17;

para constantes e nunca

#define SOME_CONST 17

Define quase sempre voltar e mordê-lo mais tarde. Consts estão na língua, e são fortemente digitado, assim você não vai obter erros estranhos por causa de alguma interação escondido. Gostaria de colocar a const no arquivo de cabeçalho apropriado. Enquanto é #pragma uma vez (ou #ifndef x / #define x / #endif), você não vai obter qualquer erros de compilação.

Em baunilha C, você pode ter problemas de compatibilidade onde você deve usar # define.

Respondeu 11/12/2008 em 01:40
fonte usuário

votos
0

Para responder a essência da sua pergunta:
Você geralmente não quiser definir uma variável estática em um arquivo de cabeçalho.
Isso faria com que você tenha variáveis duplicadas em cada uma das unidades de tradução (arquivos C) que incluem o cabeçalho.

variáveis em um cabeçalho deve realmente ser declarado extern uma vez que é a visibilidade implícita. Veja esta pergunta para uma boa explicação.

Na verdade, a situação pode não ser tão terrível, como o compilador provavelmente converter um tipo const para um valor literal. Mas você não pode querer contar com esse comportamento, especialmente se otimizações estão desligados.

Respondeu 10/12/2008 em 13:36
fonte usuário

votos
0

para o ambiente autoconf: Você sempre pode definir constantes no arquivo de configuração também. AC_DEFINE () eu acho que é a macro para definir ao longo de toda a construção.

Respondeu 10/12/2008 em 09:26
fonte usuário

votos
0

Eu gostaria de ver mais contexto para sua pergunta. O tipo do valor é crítica, mas você deixou-o para fora. O significado da palavra-chave const em C é bastante sutil; por exemplo const char * p; não significa que ponteiro p é uma constante; você pode escrever p tudo que você gosta. O que você não pode escrever é a memória que p aponta para, e isto permanece verdadeiro mesmo como alterações de valor de p. Trata-se do único caso que eu realmente compreender; em geral, o significado da colocação sutil de const me escapa. Mas este caso especial é extremamente útil para os parâmetros de função porque ele extrai uma promessa da função que a memória os pontos argumento para não ser mutado.

Há um outro caso todos especial deve saber: números inteiros. Quase sempre, constantes, inteiros nomeados devem ser definidos em um arquivo .h como literais de enumeração . tipos enum não só permitem constantes de grupo relacionadas juntos em uma maneira natural, mas também permitir-lhe os nomes dos constantes para ser visto no depurador, o que é uma enorme vantagem.

Eu escrevi dezenas de milhares de linhas de C; provavelmente centenas, se eu tentar rastreá-lo. (Wc ~ / src / c / *. C diz 85 mil, mas alguns dos que é gerado, e é claro que há um monte de código C escondido em outro lugar). Além dos dois casos sobre, eu nunca encontrou muito uso para const. Eu teria prazer em aprender um novo exemplo, útil.

Respondeu 10/12/2008 em 07:29
fonte usuário

votos
0

Eu posso lhe dar uma resposta indireta. Em C ++ (em oposição a C) constimplica static. Thatis a dizer em C ++ static consté a mesma coisa que const. Assim que lhe diz como que o corpo padrões C ++ se sente sobre a questão ou seja, todos consts deve ser estático.

Respondeu 10/12/2008 em 07:26
fonte usuário

votos
-1

Se você quiser para inline o valor em suas funções você deve usar #define MY_MAGIC_NUMBER 0x12345678
Mesmo um static const unsigned MY_MAGIC_NUMBER = 0x12345678fará com que um valor de buscar a partir de um endereço. A penalidade de desempenho não importa realmente a menos que o valor muito em loops.
Eu só uso constpara os argumentos da função.

Houve alguns comentários e para baixo de votos sobre esta resposta assim que eu testei minha suposição e visto a montagem gerada e essa resposta está errada. Basicamente #definee constdará o mesmo resultado.

Respondeu 10/12/2008 em 07:43
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more