1、基本概念 宏定义 在stm32f10x_conf.h头文件中,有如下定义:
/* #define USE_FULL_ASSERT 1 */
#ifdef USE_FULL_ASSERT
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
void assert_failed(uint8_t* file, uint32_t line);
#else
#define assert_param(expr) ((void)0)
#endif /* USE_FULL_ASSERT */
如果定义了宏USE_FULL_ASSERT,assert_param(expr)宏展开就是((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
如果没有定义宏USE_FULL_ASSERT,assert_param(expr)宏展开就是((void)0) 相当于什么也不执行
((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))是C语言的一个双目运算符
如果expr为TRUE,assert(expr)就是(void)0不执行任何动作。
如果expr为FALSE, assert(expr)就是函数assert_failed((uint8_t *)__FILE__, __LINE__))
void assert_failed(uint8_t* file, uint32_t line);只是在头文件中的函数声明,函数实体可以自己定义,例如使用printf查看。
void assert_failed(u8* file, u32 line)
{ /* User can add his own implementation to report the file name and linenumber,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file,line) */
/* Infinite loop */
while (1) { }
}
注意__FILE__和__LINE__是标准库中的宏定义
例如:GPIO_Init函数的断言宏的使用:
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
#define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \
((PERIPH) == GPIOB) || \
((PERIPH) == GPIOC) || \
((PERIPH) == GPIOD) || \
((PERIPH) == GPIOE) || \
((PERIPH) == GPIOF) || \
((PERIPH) == GPIOG))
判断输入参数GPIOx是否是GPIOA、B、C、D、E、F、G中的一个
2、C语言自定义断言函数实现断言
#include<stdio.h>
#define USE_FULL_ASSERT 1
#ifdef USE_FULL_ASSERT
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((unsigned char *)__FILE__, __LINE__))
void assert_failed(unsigned char* file, unsigned int line); /*函数声明*/
#else
#define assert_param(expr) ((void)0)
#endif /* USE_FULL_ASSERT */
int
main(int argc, char *argv)
{
int a = 0;
char str[10] = {0};
printf("请输入一个大于10的整数:");
scanf("%d", &a);
assert_param(a > 10);
printf("输入的整数是:%d\n", a);
printf("请输入一个字符串,长度不要超过%d :", sizeof(str) / sizeof(str[0]));
scanf("%s", &str);
assert_param(str != NULL && strlen(str) < 10);
printf("输入的字符串是:%s\n", str);
return(0);
}
void
assert_failed(unsigned char* file, unsigned int line)
{
printf("%s \r\n", file);
printf("%d \r\n", line);
while(1);
}
运行平台:w7+codeblocks
3、C语言库函数实现断言
#include <assert.h>
#include <stdio.h>
int main()
{
int a = 0;
char str[10] = {0};
printf("请输入一个大于10的整数:");
scanf("%d", &a);
assert(a > 10);
printf("输入的整数是:%d\n", a);
printf("请输入一个字符串,长度不要超过%d :", sizeof(str) / sizeof(str[0]));
scanf("%s", &str);
assert(str != NULL && strlen(str) < 10);
printf("输入的字符串是:%s\n", str);
return(0);
}
#include <assert.h>库中有如下定义:
#ifdef NDEBUG
/*
* If not debugging, assert does nothing.
*/
#define assert(x) ((void)0)
#else /* debugging enabled */
/*
* CRTDLL nicely supplies a function which does the actual output and
* call to abort.
*/
_CRTIMP void __cdecl __MINGW_NOTHROW _assert (const char*, const char*, int) __MINGW_ATTRIB_NORETURN;
/*
* Definition of the assert macro.
*/
#define assert(e) ((e) ? (void)0 : _assert(#e, __FILE__, __LINE__))
#endif /* NDEBUG */
从库函数中的定义可以看出,如果不需要使用C语言库函数中的断言功能
#define NDEBUG
#include <assert.h>
运行平台:w7+codeblocks