【发布时间】:2024-01-22 16:20:02
【问题描述】:
我编写了一个 C 宏来设置/取消设置 uint32 变量中的位。以下是宏的定义:
extern uint32_t error_field, error_field2;
#define SET_ERROR_BIT(x) do{\
if(x < 0 || x >63){\
break;\
}\
if(((uint32_t)x)<32U){\
(error_field |= ((uint32_t)1U << ((uint32_t)x)));\
break;\
} else if(((uint32_t)x)<64U){\
(error_field2 |= ((uint32_t)1U<<(((uint32_t)x)-32U)));\
}\
}while(0)
#define RESET_ERROR_BIT(x) do{\
if(((uint32_t)x)<32U){\
(error_field &= ~((uint32_t)1U<<((uint32_t)x)));\
break;\
} else if(((uint32_t)x) < 64U){\
(error_field2 &= ~((uint32_t)1U<<(((uint32_t)x)-32U)));\
}\
} while(0)
我正在传递一个枚举字段,如下所示:
enum error_bits {
error_chamber01_data = 0,
error_port21_data,
error_port22_data,
error_port23_data,
error_port24_data,
/*this goes on until 47*/
};
产生此警告:
左移计数 >= [-Wshift-count-overflow] 类型的宽度
我这样调用宏:
USART2->CR1 |= USART_CR1_RXNEIE;
SET_ERROR_BIT(error_usart2);
/*error_usart2 is 47 in the enum*/
return -1;
每个宏都会收到此警告,即使是左移计数
如果我在没有宏的情况下使用宏的定义,它不会产生任何警告。行为与 64 位变量相同。我正在使用 AC6 STM32 MCU GCC 编译器对 STM32F7 进行编程。 我不明白为什么会这样。谁能帮帮我?
【问题讨论】:
-
显示宏的调用位置
-
我已经编辑了帖子。
-
这个(我真的不是在这里要冒犯的意思)真正可怕的野兽是一个典型的例子,说明为什么宏对于除了简单的 true 之外的任何东西都是一个坏主意/现代 C 编译器中的虚假内容。您可以使用通常几乎没有 性能影响(如果有)的函数来编写远 更具可读性的内容。我总是首先尝试优化可读性:-)
-
我已经想过为此编写一个函数,但我想弄清楚为什么会产生警告
-
在宏中,您区分两种情况,它们本身是可以的。警告来自未执行的分支,其中班次超出范围。 (显然,这些诊断是在消除死分支之前发出的。)