【问题标题】:using different enumerated type in different levels在不同级别使用不同的枚举类型
【发布时间】:2017-12-29 02:02:30
【问题描述】:

虽然枚举是整数常量,但我在使用/组织方面存在问题。 我将串行数据接收分为三个层次。最低级别0是一个中断服务程序,在此之上我在级别1中有一个名为receiveData()的函数,在此之上我在级别2中编写了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,
};

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

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

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 值。这里我也不确定推荐的做法是什么。

【问题讨论】:

    标签: c gcc enumerated-types


    【解决方案1】:

    最简单的方法是将所有枚举组合为一个。稍微复杂一点的方法是使用“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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-11
      • 2019-03-23
      • 1970-01-01
      相关资源
      最近更新 更多