【问题标题】:Use Macro define for declaring multiple version structure in C使用宏定义在 C 中声明多个版本结构
【发布时间】:2021-03-15 14:34:22
【问题描述】:

我正在尝试解决有关具有多个版本的协议的问题。 它的结构版本会不断扩展,像下面的sn-p,1.1.2版本可能会来。

原文:

#include <stdio.h>
#include <stdint.h>

typedef struct GetReading {
    uint8_t val;
} GetReading_T;


int main()
{
    GetReading_T instaince = {0};
    instaince.val = 0x12c;
    
    printf("%02x\n", instaince.val);

    return 0;
}

之后:

#include <stdio.h>
#include <stdint.h>

#define MULTI_S(NAME, VERSION) \
typedef struct NAME##_##VERSION { 
    
#define MULTI_E(NAME, VERSION) \
} NAME##_##VERSION##_t; 

MULTI_S(GetReading, 1_1_0)
    uint8_t val;
MULTI_E(GetReading, 1_1_0)

MULTI_S(GetReading, 1_1_1)
    uint16_t val;
MULTI_E(GetReading, 1_1_1)

/*
typedef struct GetReading_1_1_0 {
    uint8_t val;
} GetReading_1_1_0_t;
typedef struct GetReading_1_1_1 {
    uint16_t val;
} GetReading_1_1_1_t;
*/

typedef union GetReading {
    GetReading_1_1_0_t v110;
    GetReading_1_1_1_t v111;
} GetReading_T;


int main()
{
    GetReading_T instaince = {0};
    instaince.v111.val = 0x12c;

    int type = 1;
    if(type == 1) {
        printf("%04x\n", instaince.v111.val);
    } else if (type == 2) {
        printf("%02x\n", instaince.v110.val); 
    }

    return 0;
}

我只是想知道这个宏技术是否太难阅读并且可能是多余的,因为它可以通过直接声明来实现相同的效果。而且我发现很难用当前的实现来扭曲宏。

C/C++有没有更好的做法来解决这类问题?

【问题讨论】:

  • 对我来说似乎非常混乱和冗长。我看不出将名称直接放入宏而不是宏有什么问题,因为这样会不那么冗长并且更容易理解恕我直言。
  • 是的,这似乎是不必要的复杂。如果只有 2 个版本,那么显然不需要抽象层。老派的解决方案是一个带有枚举类型的结构,然后是一个包含数据的联合成员。
  • @Lundin 知道了,我怀疑它将来会有大约5个版本用于一个类似的结构,并且有很多不同的结构有很多成员,最初我想使用宏因为它会让我更容易知道已经实现了哪些具有多个版本的结构。

标签: c c-preprocessor


【解决方案1】:

考虑仅使用宏来为结构生成名称。 此外,您可以不标记结构,因为它们有别名。人工解析会更容易。


#define MULTI(NAME, VERSION) NAME##_##VERSION##_t

typedef struct {
  uint8_t val;
} MULTI(GetReading, 1_1_0);

typedef struct {
  uint16_t val;
} MULTI(GetReading, 1_1_1);

typedef union GetReading {
   MULTI(GetReading, 1_1_0) v110;
   MULTI(GetReading, 1_1_1) v111;
} GetReading_T;

【讨论】:

  • 是的,看起来更干净。
  • 另外,因为只有一个地方可以放版本,所以我根本不会使用宏。必须知道宏会使代码更难掌握。无论如何:+1:
【解决方案2】:

C/C++有没有更好的做法来解决这类问题?

我强烈建议使用代码生成而不是 C 宏或 C++ 模板。

使用脚本或程序生成协议的不同版本。它将更简洁、更易于理解、编译更快且更易于维护。

您甚至可以提交生成的标头,这样您只需支付一次生成价格!

【讨论】:

  • 很好的建议。 Python 和 PHP 闪过我的脑海。你有什么建议吗?
  • 我过去曾成功使用过 Python。它现在随处可见,如果你需要解析 C 代码,甚至 Clang 都有它的绑定:)
猜你喜欢
  • 2017-09-20
  • 2018-09-09
  • 1970-01-01
  • 1970-01-01
  • 2014-04-17
  • 2010-10-11
  • 2021-12-13
  • 1970-01-01
  • 2014-11-30
相关资源
最近更新 更多