Por que o sizeof é considerado um operador?

93

Por que é sizeofconsiderado um operador e não uma função?

Qual propriedade é necessária para se qualificar como operador?

Arpit
fonte

Respostas:

181

Porque o padrão C diz isso, e ele recebe o único voto.

Como conseqüências:

  • O operando de sizeof pode ser um tipo entre parênteses sizeof (int), em vez de uma expressão de objeto.
  • Os parênteses são desnecessários: int a; printf("%d\n", sizeof a);está perfeitamente bem. Eles são frequentemente vistos, em primeiro lugar porque são necessários como parte de uma expressão de conversão de tipo e, em segundo lugar, porque sizeof tem uma precedência muito alta, então sizeof a + bnão é o mesmo que sizeof (a+b). Mas eles não fazem parte da invocação de sizeof, eles fazem parte do operando.
  • Você não pode pegar o endereço de sizeof.
  • A expressão que é o operando de sizeof não é avaliada em tempo de execução ( sizeof a++não modifica a).
  • A expressão que é o operando de sizeof pode ter qualquer tipo, exceto void ou tipos de função. Na verdade, esse é o ponto de tamanho de.

Uma função seria diferente em todos esses pontos. Provavelmente existem outras diferenças entre uma função e um operador unário, mas acho que isso é o suficiente para mostrar por que sizeof não poderia ser uma função, mesmo que houvesse uma razão para querer que fosse.

Steve Jessop
fonte
3
Nossa, exatamente o que eu estava pensando!
crashmstr
7
Não posso dizer melhor.
Clement Herreman,
Eu acredito que as coisas são mais complexas hoje em dia devido a matrizes de comprimento variável (VLA). IIRC, o padrão permitiria até mesmo sizeofefeitos colaterais se houvesse um VLA na expressão.
Aaron McDaid
@glglgl Não, isso não faz sentido. Nesse contexto, (int)não é nada sofisticado - apenas o nome de um tipo entre parênteses. Os parênteses aqui são uma parte da sintaxe de sizeof- eles são obrigatórios ao tirar o tamanho de um tipo, mas não são obrigatórios ao tirar o tamanho de uma expressão. Veja, por exemplo, aqui
anatolyg
1
O padrão usa duas notações para sizeof: sizeof unary-expressione sizeof ( type-name )- portanto, no padrão C11 não é considerado um 'elenco', mas um nome de tipo entre parênteses. O resultado líquido é praticamente o mesmo. (Para comparação, uma expressão de elenco é ( type-name ) cast-expression.) E odeio a maneira como o Markdown de comentário funciona de forma diferente do Markdown de perguntas e respostas!
Jonathan Leffler
24

Ele pode ser usado como uma constante de tempo de compilação, o que só é possível se for um operador em vez de uma função. Por exemplo:

union foo {
    int i;
    char c[sizeof(int)];
};

Sintaticamente, se não fosse um operador, teria que ser uma macro do pré-processador, pois as funções não podem aceitar tipos como argumentos. Essa seria uma macro difícil de implementar, pois sizeofpode aceitar os tipos e as variáveis ​​como argumento.

John Kugelman
fonte
4
+1, mas observe que não é uma constante de tempo de compilação quando o argumento é um VLA - array de comprimento variável.
Jonathan Leffler,
6

Porque o padrão C diz isso, e ele recebe o único voto.

E o padrão provavelmente está correto porque sizeofleva um tipo e

Em geral, se o domínio ou codomínio (ou ambos) de uma função contiver elementos significativamente mais complexos do que os números reais, essa função é chamada de operador. Inversamente, se nem o domínio nem o codomínio de uma função contiverem elementos mais complicados do que os números reais, é provável que essa função seja chamada simplesmente de função. Funções trigonométricas como cosseno são exemplos do último caso.

Além disso, quando as funções são usadas com tanta frequência que evoluíram com notações mais rápidas ou mais fáceis do que a forma F (x, y, z, ...) genérica, as formas especiais resultantes também são chamadas de operadores. Os exemplos incluem operadores infixos, como adição "+" e divisão "/", e operadores pós-fixados, como fatorial "!". Esse uso não está relacionado à complexidade das entidades envolvidas.

(Wikipedia)

Daniel Brückner
fonte
Isso provavelmente explica a motivação do padrão C (e outras linguagens de programação) em usar os termos "operador" e "função" como o fazem.
Steve Jessop,
5

Porque não é uma função. Você pode usá-lo assim:

int a;
printf("%d\n", sizeof a);

A função tem um ponto de entrada, código, etc. A função deve ser executada em tempo de execução (ou embutida), sizeof deve ser determinado em tempo de compilação.

Michał Górny
fonte
2

O operador sizeof é uma entidade em tempo de compilação, não em tempo de execução e não precisa de parênteses como uma função. Quando o código é compilado, ele substitui o valor pelo tamanho daquela variável em tempo de compilação, mas na função após a função ser executada, saberemos o valor de retorno.

Deepak Kumar 'SORTED'
fonte
1

Porque:

  • quando você passa um valor para uma função, o tamanho do objeto não é passado para a função, então uma sizeof"função" não teria como determinar o tamanho
  • em C, as funções só podem aceitar um tipo de argumento; sizeof () precisa aceitar todos os tipos de coisas diferentes (variáveis, bem como tipos! Você não pode passar um tipo para uma função em C)
  • chamar uma função envolve fazer uma cópia dos argumentos e outras despesas desnecessárias
Artelius
fonte
1

Há uma pequena diferença em relação à função - o valor de sizeof é resolvido em tempo de compilação, mas não em tempo de execução!

Orvalhado
fonte
7
Exceto para VLA - array de comprimento variável - argumentos.
Jonathan Leffler,
1

Porque é um operador em tempo de compilação que, para calcular o tamanho de um objeto, requer informações de tipo que só estão disponíveis em tempo de compilação. Isso não vale para C ++.

João silva
fonte
0

sizeof()operador é um tempo de compilação seria a ocorrência. Ele pode ser usado para determinar os parâmetros ou argumentos.

ganesh
fonte
-1

Sizeof (), acho que obviamente é uma função e um operador. Por quê? Porque uma função contém parênteses para entrada no estágio de entrada. Mas, principalmente, os operadores de causa do operador são caracteres de ação, portanto, sizeof é uma instrução de ação que atua no operando entre parênteses.

Enoch Asanda Hall
fonte