用编译时断言在早期发现错误
发布时间:2007/4/23 0:00:00 访问次数:645
|
您现在的位置:LINE 的货源和报价 LINE 的相关技术信息 | 其他型号 | 北京全友伟业科技有限公司联系人:张先生、吴小姐、李小姐 电话:010-82824780-82772818-82771348-82824782-82774107 | 北京全友伟业科技有限公司联系人:张先生/吴小姐/李小姐 电话:010-82824780-82772818-82771348-82824782-82774107 | 北京全友伟业科技有限公司联系人:张先生/吴小姐/李小姐 电话:010-82824782-82824780-82772818-82771348-82774107 | 北京科诚达信电子科技有限公司联系人:石小姐 王小姐 电话:010-823507548/82350784/81671645/86713717 | ||
>>更多供应商 |
用编译时断言在早期发现错误
一段时间以来,笔者一直在讨论如何在C和C++中使用结构来定义LINE 18
将断言写入到代码中能帮助进行归档,并提高开发代码的成功率。然而,因为是写到stderr,在缺乏对 标准C I/O系统支持的嵌入式环境中,标准的断言宏毫无用处。然而,写你自己的断言宏版、在别的地方显示消息并不那么困难。
尽管断言宏可以是一种有用的调试辅助手段,但并不适合于处理在已付运的终端用户产品中的运行时错误。已付运的产品应该产生对于一般终端用户来说很有意义的诊断消息。它还应该比通过调用中断函数更可靠地恢复或关断程序的执行。因此,提供了一种在源代码很少或不改变的情况下使所有断言无效的简单方法。开发者可以在代码中保留断言作为文档,但是应该使它们不会产生代码。
如果在包入之前在源文件中定义NDEBUG宏,断言宏将这样简单地定义:
#define assert(cond) ((void)0)
因此,随后的调用诸如:
assert(f != NULL);
扩展为:
((void)0);
编译器能够优化这个语句,使其根本不会产生代码。
可以在包入指令前,将NDEBUG的定义写入到源代码中:
#define NDEBUG
#include }
这种方法的问题是,每次想打开或者关闭断言的时候必须修改源程序。大多数编译器允许在调用编译器的时候,通过使用命令行自变量来定义宏,通常选择D选项。例如,像下面的命令行出现在源程序的第一行之前,则将断言关断:
cc -DNDEBUG get_token.c
compiles get_token.c as if:
#define NDEBUG
使用预处理程序的编译时断言
开发者可以使用断言来验证存储器映射结构成员具有正确的尺寸和排列。例如,假设像下面这样为一个定时器定义器件寄存器:
typedef struct timer timer;}
struct timer
{
uint8_t MODE;
uint32_t DATA;
uint32_t COUNT;
};
可以使用一个断言和offsetof宏来验证DATA成员在结构内部具有偏移4,如下:
assert(offsetof(timer, DATA) == 4);
在标准C头文件
|
您现在的位置:LINE 的货源和报价 LINE 的相关技术信息 | 其他型号 | 北京全友伟业科技有限公司联系人:张先生、吴小姐、李小姐 电话:010-82824780-82772818-82771348-82824782-82774107 | 北京全友伟业科技有限公司联系人:张先生/吴小姐/李小姐 电话:010-82824780-82772818-82771348-82824782-82774107 | 北京全友伟业科技有限公司联系人:张先生/吴小姐/李小姐 电话:010-82824782-82824780-82772818-82771348-82774107 | 北京科诚达信电子科技有限公司联系人:石小姐 王小姐 电话:010-823507548/82350784/81671645/86713717 | ||
>>更多供应商 |
用编译时断言在早期发现错误
一段时间以来,笔者一直在讨论如何在C和C++中使用结构来定义LINE 18
将断言写入到代码中能帮助进行归档,并提高开发代码的成功率。然而,因为是写到stderr,在缺乏对 标准C I/O系统支持的嵌入式环境中,标准的断言宏毫无用处。然而,写你自己的断言宏版、在别的地方显示消息并不那么困难。
尽管断言宏可以是一种有用的调试辅助手段,但并不适合于处理在已付运的终端用户产品中的运行时错误。已付运的产品应该产生对于一般终端用户来说很有意义的诊断消息。它还应该比通过调用中断函数更可靠地恢复或关断程序的执行。因此,提供了一种在源代码很少或不改变的情况下使所有断言无效的简单方法。开发者可以在代码中保留断言作为文档,但是应该使它们不会产生代码。
如果在包入之前在源文件中定义NDEBUG宏,断言宏将这样简单地定义:
#define assert(cond) ((void)0)
因此,随后的调用诸如:
assert(f != NULL);
扩展为:
((void)0);
编译器能够优化这个语句,使其根本不会产生代码。
可以在包入指令前,将NDEBUG的定义写入到源代码中:
#define NDEBUG
#include }
这种方法的问题是,每次想打开或者关闭断言的时候必须修改源程序。大多数编译器允许在调用编译器的时候,通过使用命令行自变量来定义宏,通常选择D选项。例如,像下面的命令行出现在源程序的第一行之前,则将断言关断:
cc -DNDEBUG get_token.c
compiles get_token.c as if:
#define NDEBUG
使用预处理程序的编译时断言
开发者可以使用断言来验证存储器映射结构成员具有正确的尺寸和排列。例如,假设像下面这样为一个定时器定义器件寄存器:
typedef struct timer timer;}
struct timer
{
uint8_t MODE;
uint32_t DATA;
uint32_t COUNT;
};
可以使用一个断言和offsetof宏来验证DATA成员在结构内部具有偏移4,如下:
assert(offsetof(timer, DATA) == 4);
在标准C头文件
上一篇:嵌入式系统引导技术研究