/* Exported types ------------------------------------------------------------*/
 /* Exported constants --------------------------------------------------------*/
 /* Uncomment the line below to expanse the "assert_param" macro in the 
    Standard Peripheral Library drivers code */
 /* #define USE_FULL_ASSERT    1 */
 
 /* Exported macro ------------------------------------------------------------*/
 #ifdef  USE_FULL_ASSERT
 
 /**
   * @brief  The assert_param macro is used for function\'s parameters check.
   * @param  expr: If expr is false, it calls assert_failed function which reports 
   *         the name of the source file and the source line number of the call 
   *         that failed. If expr is true, it returns no value.
   * @retval None
   */
   #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
 /* Exported functions ------------------------------------------------------- */
   void assert_failed(uint8_t* file, uint32_t line);
 #else
   #define assert_param(expr) ((void)0)
 #endif /* USE_FULL_ASSERT */

看到一个宏, 它大概是这样的:
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((u8 *)__FILE__, __LINE__))

代码的含意简单, 关键是那个 (void)0 的用法, 我还是第一次见到(别笑).

我用 void 的时候, 有两种情况:
1.放到函数前面, 强调函数没有返回值, 也就是说函数不能作右值
如: void fun(int x);
2.放到函数形参里面, 强调函数无任何参数
如: int fun(void);

还有一种用法是:
#define NULL ((void*)0)

当然, 这就是NULL空指针的定义方式(在 stdlib.h 里面).

可, 上面宏的 (void)0 , 一开始确实让我觉得有点奇怪, 不知道干嘛的, 平静下来, 想了想.

原来, 宏里面这样用的目的是防止该宏被用作右值, (void)0 本身也不能作右值, 因为 void 非实际的类型!

版权声明:本文为sinferwu原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/sinferwu/articles/7494015.html