Aqui está o código compilado nas janelas dev c ++:
#include <stdio.h>
int main() {
int x = 5;
printf("%d and ", sizeof(x++)); // note 1
printf("%d\n", x); // note 2
return 0;
}
Espero x
ser 6 depois de executar a nota 1 . No entanto, a saída é:
4 and 5
Alguém pode explicar por x
que não aumenta após a nota 1 ?
VLAs
nenhuma das outras.Respostas:
Do padrão C99 (a ênfase é minha)
fonte
N
em stdin e makeint array[N]
. Este é um dos recursos do C99, indisponível no C ++.sizeof(int[++x])
(realmente, realmente uma péssima idéia), ele++
poderia ser avaliado.gcc
,clang
e em ideone.com/Pf7iFsizeof
é um operador em tempo de compilação, portanto, no momento da compilaçãosizeof
e seu operando, é substituído pelo valor do resultado. O operando não é avaliado (exceto quando é uma matriz de comprimento variável); apenas o tipo do resultado é importante.Resultado:
como
short
ocupa 2 bytes na minha máquina.Alterando o tipo de retorno da função para
double
:dará
8
como saída.fonte
sizeof(foo)
tenta muito descobrir o tamanho de uma expressão em tempo de compilação:6.5.3.4:
Em resumo: matrizes de comprimento variável, executadas em tempo de execução. (Nota: Matrizes de comprimento variável são um recurso específico - não matrizes alocadas com
malloc(3)
.) Caso contrário, apenas o tipo da expressão é calculado e o mesmo no momento da compilação.fonte
sizeof
é um operador interno em tempo de compilação e não é uma função. Isso fica muito claro nos casos em que você pode usá-lo sem os parênteses:fonte
sizeof
operador não é um operador em tempo de compilação, você só precisa fornecer um VLA para descobrir isso.Nota
Esta resposta foi mesclada a partir de uma duplicata, o que explica a data final.
Original
Exceto para matrizes de comprimento variável, sizeof não avalia seus argumentos. Podemos ver isso a partir da seção padrão projecto C99
6.5.3.4
O operador sizeof parágrafo 2 , que diz:Um comentário ( agora removido ) perguntou se algo assim seria avaliado em tempo de execução:
e, de fato, algo assim também funcionaria ( veja os dois ao vivo ):
já que ambos são matrizes de comprimento variável. Embora eu não veja muito uso prático em nenhum deles.
Observe que as matrizes de comprimento variável são abordadas no parágrafo 4 da seção C99 da seção padrão do rascunho :
6.7.5.2
Atualizar
Em C11, a resposta muda para o caso VLA; em certos casos, não é especificado se a expressão de tamanho é avaliada ou não. Na seção
6.7.6.2
Declaradores de matriz, que diz:Por exemplo, em um caso como este ( veja ao vivo ):
fonte
sizeof
é efetivamente uma macro - ela não cria código, mas pré-computa o valor esperado e o deposita diretamente no código. Note-se que esta foi a única comportamento até C99, como VBAs não existia (i nunca tinha realmente ouvido falar deles até esta resposta, acredite ou não!)sizeof (char[x++]);
o valor de usariax
algo diferente de determinar o valor da expressãox++
e o novo valor dex
, os quais são normais com esse operador?char[x++]
é um VLA. parece efetivamente como umchar*
para meus olhos desconhecidos.Como o operando do
sizeof
operador não é avaliado, você pode fazer isso:Demonstração on-line: http://ideone.com/S8e2Y
Ou seja, você não precisa definir a função
f
se ela for usadasizeof
apenas. Essa técnica é usada principalmente na metaprogramação de modelos C ++, pois mesmo em C ++, o operando desizeof
não é avaliado.Por que isso funciona? Funciona porque o
sizeof
operador não opera com valor , mas com o tipo de expressão. Portanto, quando você escrevesizeof(f())
, ele opera com o tipo de expressãof()
e que nada mais é do que o tipo de retorno da funçãof
. O tipo de retorno é sempre o mesmo, independentemente do valor que a função retornaria se realmente fosse executada.No C ++, você pode até isso:
No entanto, parece que,
sizeof
primeiro, eu estou criando uma instância deA
, escrevendoA()
e depois chamando a funçãof
na instância, escrevendoA().f()
, mas isso não acontece.Demonstração: http://ideone.com/egPMi
Aqui está outro tópico que explica algumas outras propriedades interessantes de
sizeof
:fonte
A execução não pode acontecer durante a compilação. Então
++i
/i++
não vai acontecer. Tambémsizeof(foo())
não executará a função, mas retornará o tipo correto.fonte
sizeof
é uma expressão constante do tempo de compilação"?sizeof
é executado em tempo de compilação, masx++
só pode ser avaliado em tempo de execução. Para resolver isso, o padrão C ++ determina que o operando desizeof
não seja avaliado. O Padrão C diz:fonte
sizeof()
O operador fornece apenas o tamanho do tipo de dados; ele não avalia os elementos internos.fonte
sizeof()
operador age recursivamente e obterá o tamanho em bytes de todos os elementos de um contêiner, membros de uma classe ou estrutura etc. Você pode provar isso facilmente, criando uma classe simples com alguns membros e chamandosizeof()
por isso. (No entanto, qualquer coisa lá dentro, que seja um ponteiro, não pode ver o tamanho de - apenas o tamanho do ponteiro.) Isso acontece em tempo de compilação, como outros comentadores declararam: as expressões dentrosizeof()
do não são avaliadas.