Desenvolvimento - C/C++
Como pegar o sizeof de um membro de um struct...
Veja nesse artigo como pegar o sizeof de um membro de um struct sem alocar uma variável.
por Wanderley Caloni Jr...sem alocar uma variável? Exemplo:
static const size_t FIELD_SIZE_MSGID = 15; struct FEEDER_RECORD_HEADER { char MessageID[FIELD_SIZE_MSGID]; char MessageIndex[10]; }; // error C2143: syntax error: missing ")" before "." char MessageIndexBuffer[sizeof(FEEDER_RECORD_HEADER.MessageIndex) + 1]; // error C2070: "": illegal sizeof operand char MessageIndexBuffer[sizeof(FEEDER_RECORD_HEADER::MessageIndex) + 1];
Na primeira tentativa, até que bem-intencionada, é mais ou menos previsível que não funcione. O erro gerado pelo compilador não é sequer claro. O operador de acesso a membros (o ponto) precisa ter à sua esquerda alguma variável ou constante do tipo do struct que tem o membro acessado. Como o operando no caso é o nome do próprio tipo, nada feito. Mas valeu o teste. É muito importante ver as coisas acontecerem para que sejamos menos influenciados pelo poder da desinformação.
A segunda tentativa é mais próxima da realidade e de onde queremos chegar. O erro do compilador até nos dá uma dica! Nós acessamos o membro do struct certo, mas da maneira errada. Como o membro não é estático, ou seja, pertencente ao struct, não tem como acessar apenas pelo escopo. Precisamos de um objeto criado. Mas para termos um objeto criado supõe-se que devemos criá-lo. Ora, mas isso é exatamente o que NÃO queremos em nossa solução.
A Zona Morta do C++
Esse problema traz à lembrança uma curiosa particularidade no operador sizeof: ele NÃO avalia as expressões usadas como operandos. Como é isso? Bom, como o objetivo do sizeof é fornecer a quantidade de memória que a expressão ocupa, logo não faz sentido que ele também a execute. Muito lógico para uma linguagem que prima por eficiência e clareza, não? Se você quiser executar a expressão, basta colocá-la fora do sizeof também.
Sabemos então que nada que a gente coloque dentro de um sizeof vai ser realmente executado. É mais ou menos como a "zona morta" do c++, o lugar onde - se tratando de código executável - nada existe. Isso quer dizer que podemos construir um objeto lá dentro que na verdade ele não constrói! Vejamos o assembly de um negócio desses:
sz = sizeof( (new FEEDER_RECORD_HEADER)->MessageID ); // mov dword ptr [sz],0Fh
Nada é alocado, conseguimos o que queríamos. Isso mostra mais uma vez que a aparente "pequeneza" de algumas características da linguagem só se revelam fundamentais quando mais precisamos delas.
Artigo original: Caloni.com.br