O que é um C comum / C ++ macro para determinar o tamanho de um membro de estrutura?

StackOverflow https://stackoverflow.com/questions/1400660

  •  05-07-2019
  •  | 
  •  

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!

Foi útil?

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);  
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top