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