Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

164
Visualizações
Is there a better way to compare two C structs?

Let's assume that I declared a C struct for holding configuration information, which has lots of fields(~30), e.g.:

struct config {
    int a;
    int b;
    int c;
    ...
    char *str1;
    char *str2;
    ...
};

What is the best way to compare two structs without simply enumerating and comparing each element? Of course I could use the following code but my question is, is there an easier way to achieve this?

static int
cmpInstances(struct config *l, struct config *r) {
    return (
        l->a == r->a &&
        l->b == r->b &&
        l->c == r->c &&
        !strcmp(l->str1, r->str1) &&
        !strcmp(l->str2, r->str2)
    );
}

Is there some macro that could do that? For example: cmpInstancesViaMacro(a,b,c) would expand into

   l->a == r->a &&
   l->b == r->b &&
   l->c == r->c
over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

A generalized variant of so-called X Macros could be used.

In the example of the question, it would look like this:

#define CONFIG_FIELDS \
  X_INT(a) \
  X_INT(b) \
  X_INT(c) \
  X_STRING(str1) \
  X_STRING(str2)

struct config {
  #define X_INT(NAME) int NAME;
  #define X_STRING(NAME) char *NAME;
    CONFIG_FIELDS
  #undef X_INT
  #undef X_STRING
};

static int cmpInstances(struct config *l, struct config *r) {
  #define X_INT(NAME) l->NAME == r->NAME &&
  #define X_STRING(NAME) strcmp(l->NAME, r->NAME) == 0 &&
    return CONFIG_FIELDS 1;
  #undef X_INT
  #undef X_STRING
}

With this solution, only the CONFIG_FIELDS macro needs to be changed when the structure is changed as long as there is no change to the set of types used. The structure and function would automatically be kept synchronized.

If a new type is introduced, the corresponding X Macros must be defined similar to X_INT and X_STRING above.

over 4 years ago · Santiago Trujillo Relatório

0

Perhaps some macros will help us reduce the lines of code and effort needed:

#define CMP(name) l->name == r->name &&
#define SCMP(name) !strcmp(l->name, r->name) &&

struct config
{
    int a;
    int b;
    int c;
    char *str1;
    char *str2;
};

static int cmpInstances(struct config *l, struct config *r) 
{
    return CMP(a) CMP(b) CMP(c) SCMP(str1) SCMP(str2) 1;
}

#undef CMP
#undef SCMP

Here we define some macros that take only the name of the variable and compare them. One is written for integer comparison (CMP) and the other is written for string comparison (SCMP). Then you can use these macros to compare your data and undef them when you are done.

Thanks to chqrlie for adding 1 part.

over 4 years ago · Santiago Trujillo Relatório

0

What is the best way to compare two structs without simply enumerating and comparing each element?

The presented way is the best. Except, the pointers should point to const - nothing is getting modified.

is there an easier way to achieve this?

The presented way is the easiest way to achieve it, it's also the most readable and self-explanatory, easy to refactor and reason about. Any other will add to complexity and result in maintenance burden.

I find strcmp(...) == 0 clearer then !strcmp(...).

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda