O que é um C comum / C ++ macro para determinar o tamanho de um membro de estrutura?
Pergunta
C / C ++, como determinar o tamanho da variável membro de uma estrutura sem a necessidade de definir uma variável binária de que tipo de estrutura? Aqui está um exemplo de como fazê-lo errado, mas mostra a intenção:
typedef struct myStruct {
int x[10];
int y;
} myStruct_t;
const size_t sizeof_MyStruct_x = sizeof(myStruct_t.x); // error
Para referência, este deve ser como encontrar o tamanho do 'x' se você primeiro definir uma variável dummy:
myStruct_t dummyStructVar;
const size_t sizeof_MyStruct_x = sizeof(dummyStructVar.x);
No entanto, eu estou esperando para evitar ter que criar uma variável dummy apenas para obter o tamanho do 'x'. Eu acho que há uma maneira inteligente de reformulação 0 como um myStruct_t para ajudar a encontrar o tamanho da variável de membro 'x', mas foi tempo suficiente para que eu tenha esquecido os detalhes, e não consigo obter uma boa pesquisa no Google sobre este . Você sabe?
Obrigado!
Solução
Em C ++ (que é o que as marcas dizem), o seu código "dummy" pode ser substituída por:
sizeof myStruct_t().x;
No myStruct_t objeto será criado:. O compilador só funciona para fora o tipo estático do operando de sizeof, ele não executa a expressão
Isso funciona em C e em C ++ é melhor porque ele também funciona para as classes sem um construtor sem argumentos acessíveis:
sizeof ((myStruct_t *)0)->x
Outras dicas
Eu estou usando seguinte macro:
#include <iostream>
#define DIM_FIELD(struct_type, field) (sizeof( ((struct_type*)0)->field ))
int main()
{
struct ABC
{
int a;
char b;
double c;
};
std::cout << "ABC::a=" << DIM_FIELD(ABC, a)
<< " ABC::c=" << DIM_FIELD(ABC, c) << std::endl;
return 0;
}
truque é tratar 0 para o ponteiro para a sua estrutura. Esta é resolvido em tempo de compilação para que ele segura.
Você pode facilmente fazer
sizeof(myStruct().x)
parâmetro como sizeof nunca é executado, você não é realmente criar esse objeto.
Qualquer um destes deve funcionar:
sizeof(myStruct_t().x;);
ou
myStruct_t *tempPtr = NULL;
sizeof(tempPtr->x)
ou
sizeof(((myStruct_t *)NULL)->x);
Porque sizeof
é avaliada em tempo de compilação, não em tempo de execução, você não terá um problema dereferencing um ponteiro NULL.
Em C ++ 11, isto pode ser feito com sizeof(myStruct_t::x)
. C ++ 11 também acrescenta std :: declval , que pode ser utilizado para este (entre outras coisas):
#include <utility>
typedef struct myStruct {
int x[10];
int y;
} myStruct_t;
const std::size_t sizeof_MyStruct_x_normal = sizeof(myStruct_t::x);
const std::size_t sizeof_MyStruct_x_declval = sizeof(std::declval<myStruct_t>().x);
De minha macros utilidade cabeçalho:
#define FIELD_SIZE(type, field) (sizeof(((type *)0)->field))
invocado assim:
FIELD_SIZE(myStruct_t, x);