Eu já vi dois estilos de uso sizeof
para operações relacionadas à memória (como em memset
ou malloc
):
sizeof(type)
esizeof variable
ousizeof(variable)
Qual deles você prefere, ou você usaria uma mistura dos dois estilos, e quando você usaria cada estilo? Quais são os prós e os contras de cada estilo e quando você os usa?
Como exemplo, posso ver o seguinte par de situações em que um estilo ajuda e o outro não:
Quando você errar o ponteiro indireto:
type *var;
...
memset(var, 0, sizeof var); /* oops */
Quando o tipo muda:
new_type var; /* changed from old_type to new_type */
...
memset(&var, 0, sizeof(old_type)); /* oops */
c
coding-style
congusbongus
fonte
fonte
array
é de fato um array C,sizeof(array)
retorna o número de bytes necessários para armazenar os elementos do array . Searray
é um ponteiro para o primeiro elemento de uma matriz C deteriorada, sua declaração é válida. Passar uma matriz C como argumento de função faz com que pareça um ponteiro na função - todas as informações que provam que era uma matriz, como seu tamanho, são perdidas. É por isso que está deteriorado . Erro 2: "matrizes não existem realmente em C; ... simplesmente açúcar sintático para ponteiros".A preferência (como sempre) é refletir sua intenção o mais diretamente possível.
A intenção é operar contra a memória de uma variável existente?
sizeof(variable)
Nesse caso, use , pois isso mostra o mais próximo possível que é da memória da variável em si que você se importa.A intenção é realizar algum cálculo no tipo, por exemplo, para determinar quanta memória deve ser alocada para uma nova instância? Se sim, então use
sizeof(type)
.Ou seja, eu prefiro
sobre
como o último caso parece que você está tentando acessar uma variável que ainda não existe.
Por outro lado, eu prefiro
sobre
como a intenção é claramente preencher com zero o conteúdo da variável, é a variável na qual devemos operar. Tentar usar os metadados de tipo apenas confunde as coisas aqui.
fonte
void *
são automaticamente convertidos para outros tipos de ponteiros como uma característica incorreta.Eu preferiria muito
sizeof(type)
maissizeof variable
. Mesmo que o obriga a se preocupar mais com o tipo e fazer mais mudanças, ele ajuda a evitar erros ponteiro indireç~ao, que estão entre a causa mais comum de erros em C .Eu não me preocuparia tanto com bugs onde o tipo
sizeof(type)
é alterado; sempre que alterar o tipo de uma variável, faça uma varredura rápida para ver onde essa variável é usada e se é necessário alterar algumasizeof(type)
instrução. Embora sempre exista uma chance de errar, há um risco muito menor do que erros de indicação indireta.Uma vantagem
sizeof variable
é para matrizes, mas, na prática, descobri que passar matrizes como pares de primeiro / len é muito mais comum (nesse caso, basta usar o comprimento), além disso, também é muito fácil errar o tamanho devido a deterioração da matriz / ponteiro, como neste exemplo:fonte
sizeof var
; se é um ponteiro ésizeof *var
. Isso também é algo que as pessoas podem errar, e o compilador o aceitará sem reclamar. Argumento que esses erros são muito mais difíceis de detectar e são mais comuns do que erros nosizeof(type)
formulário.C
, a publicação do código C é mais informativa do que o código C ++mat3_t::mat3_t(...)
.O objetivo é remover a redundância. Se você usar sizeof para uma operação relacionada a uma variável, obviamente você refletirá isso no sizeof. Sim, você pode errar como no primeiro exemplo, mas a cura não é do tipo use, mas * var, correspondendo corretamente ao objetivo.
Para mitigar esses problemas, é comum o uso de macros, modelos e ferramentas similares treinadas para o caso de uso, em vez do tamanho simples.
Veja minha macro CLEAR, usada exclusivamente em vez do memset nu. Salvei minha bunda várias vezes em casos de erro de digitação indireto ou quando um conteúdo struct pegou um vetor ou string ...
fonte
A lógica de negócios define sua escolha.
Se seu código se refere a uma variável específica e sem essa variável, seu código não faz sentido - escolha
sizeof(var)
Se você codificar lida com um conjunto de variáveis com um tipo específico - escolha
sizeof(type)
. Normalmente, você precisa disso se tiver umtypedef
que define muitas variáveis que você processa de maneira diferente com base em seu tipo (por exemplo, serialização). Você pode não saber quais dessas variáveis permanecerão em futuras versões de código, portanto, escolher o tipo como argumento é logicamente correto. Mesmo alterar issotypedef
não afetará seu tamanho da linha.fonte
Dependendo do tamanho da finalidade (variável), pode ser a melhor solução. Dessa forma, você pode alterar seu tipo de variável, se necessário, sem corrigir todas as entradas para o tipo. Mas, novamente, isso depende do seu objetivo.
fonte