c - 在不同级别使用不同的枚举类型

标签 c gcc enumerated-types

虽然枚举是整数常量,但我对使用/组织有疑问。 我将串行数据接收分为三个级别。最低的 level0 是一个中断服务例程,在其之上我在 level 1 中有一个名为 receiveData() 的函数,而在 level2 之上我已经编写了 processReceivedFrame()。我有两种枚举类型,一种用于 0 级和 1 级,另一种用于 2 级。类似地,一种用于传输的枚举类型。

   enum FRAME_RECEIVE_STATUS
    {
        FR_STS_FRAME_NOT_RECEIVED=0,            // Initial state by default
        FRAME_RECEIVED,                 // Indicates that frame is received by interrupt vector

        FIRST_START_BYTE_RECVD,        // Set as soon as first start byte is received in case of multiple start bytes
        RECV_PROGRESS,                 //Indicates that the receiving is in progress
        INVALID_DATA_LENGTH,        // This status is updated if length byte is invalid. We are verifying only against minimum possible length.
        RX_BUFFER_FULL,             // ISR will update this status in case buffer is full
        INVALID_START_BYTE,         // This will be set when first start byte is received, but second byte is incorrect.
        FIRST_END_BYTE_RECEIVED,    // Set as soon as first end byte is received.
       };

    enum FRAME_PROCESS_STATUS
    {
        FRAME_VALID=100,
        FP_STS_FRAME_NOT_RECEIVED,
        CHECKSUM_SUCCESS,               //
        CHECKSUM_ERROR,
    };
enum TRANSMIT_STATES
{
    FRAME_SEND_SUCCESS=0,
    FRAME_SEND_RESPONSE_TIMEOUT,
    FRAME_SEND_RESP_WAITING,
    INVALID_RESPONSE_BYTE,
    EXCEEDED_MAX_ATTEMPTS,
    TRANSMIT_BUFFER_FULL,
};

但现在我觉得如果我去不同的枚举类型我有困难。特别是在 level1 中,我最终会根据特定条件返回 level 2 枚举类型。在某些地方,如果使用不同的类型,我会收到警告。

那么通常使用枚举类型进行错误处理的最佳方式是什么?可能是用于相关功能的单个枚举类型,例如用于接收的 (RECEIVE_STATES) 和用于传输的 (TRANSMIT_STATES)?但即使在这种情况下,我们最终也可能会混合不同的类型。例如,假设我正在传输一些数据然后等待响应。响应可能是枚举类型的 RECEIVE_BUFFER_FULL RECEIVE_STATES。如果函数返回类型是 enum TRANSMIT_STATES,但在此过程中获取 RECEIVE_STATES 的枚举,我们可能会再次遇到问题并通过替换适当的 enum 元素在代码中处理该问题类型。例如:-

enum TRANSMIT_STATES sendDataByte(char );     // Forward declaration.
enum RECEIVE_STATES receiveData(char *);  // Forward declaration.
enum TRANSMIT_STATES transmitData(char *data)
{
     for(.....)
     {
     enum TRANSMIT_STATES t_Status = sendDataByte(*(data+i));   // Transmit the data
      if(t_Status==TRANSMIT_BUFFER_FULL)
       return(t_Status);
     }
     // Wait for the response
     enum RECEIVE_STATES r_Status = receiveData(data);
     // Alternatively, t_Status = receiveData(data);
     if(rStatus==RX_BUFFER_FULL)
     t_Status=RX_BUFFER_FULL;  // Assigning different type
     return(t_Status);
}

在上面的代码中,如果我去:-

t_Status = receiveData(); 

我有分配不同类型的问题。即使在以下情况下:-

r_Status = receiveData(data);

我必须检查状态并从 TRANSMIT_STATES 返回适当的代码。我不能在两种不同类型中使用相同的枚举元素。所以维护不同的名字也是一个问题。 那么在这种情况下,建议对所有类型的错误使用一个组合枚举?但是,如果我们为较低级别使用一些标准库,那么这些库可能会使用不同类型的枚举或普通 int 值。在这里我也不确定推荐的做法是什么。

最佳答案

最简单的是将所有枚举合并为一个。一种稍微复杂一些的方法是使用“tagged union”又名变体:

enum ERROR_TYPE {
    SUCCESS = 0,
    TRANSMIT,
    RECEIVE
};
struct result_t {
    enum ERROR_TYPE err; // 0 means no error, i.e. success
    union {
        enum TRANSMIT_STATES err_send; // err 1
        enum RECEIVE_STATES err_recv; // err 2
    };
};

然后你的代码看起来像这样:

struct result_t transmitData(char *data)
{
    struct result_t result = {SUCCESS};
    for(...)
    {
        result.err_send = sendDataByte(*(data+i));   // Transmit the data
        if(result.err_send==TRANSMIT_BUFFER_FULL) {
            result.err = TRANSMIT;
            return(result);
        }
    }
    // Wait for the response
    result.err_recv = receiveData(data);
    if(result.err_recv==RX_BUFFER_FULL) {
        result.err = RECEIVE;
    }
    return(result);
}

关于c - 在不同级别使用不同的枚举类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45264420/

相关文章:

c# - 将字符串转换为 char* 到字符串(C# -> C -> C++)

c - "error: expected expression before struct"在宏参数到 `offsetof` 与 musl 的宏函数内

c++ - 当 int 不是 int (intX_t)

python - 理解Python中的枚举

jpa - @Enumerated(EnumType.STRING) 导致没有为值 [0] 提供转换值

c++ - 反转链表(通过递归)不起作用

c - 如何传递和接收指向结构数组的指针?

c++ - c 中令人困惑的空值

c++ - "error: too many #pragma options align=reset"在 mac 上与 gcc 4.8

vhdl - 枚举中的字 rune 字别名的正确语法是什么?