虽然枚举是整数常量,但我对使用/组织有疑问。
我将串行数据接收分为三个级别。最低的 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/