更可移植的编译时断言() [英] more portable compile-time assert()

查看:70
本文介绍了更可移植的编译时断言()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




我正在使用一个类似断言()的宏来测试一个常量表达式

编译时间


#define ASSERT(条件)struct {char assert_failure [(条件)?

1:-1];}


想法是这个宏导致编译错误如果一个常数

条件

不是真的(或者如果条件不是常数),有一些

(非常神秘)

错误信息,例如错误:数组大小`assert_failure''是

负数。

这适用于涉及sizeof的表达式和强制转换

(假设编译器没有损坏并知道如何执行

算术

作为目标系统),例如


struct {char this,that; } foo;

ASSERT(2 == sizeof foo); //检查foo的大小


#define LOW8(x)((unsigned char)(x))

ASSERT(LOW8(0x1A5)== 0xA5 ); //检查LOW8的工作原理


int main(void){return 0;}

这适用于多个编译器,但< OT> GCC< / OTbarks带有警告

在未命名的struct / union定义没有实例的曲调上。


我正在寻找一种更便携的替代品。想出了


#define ASSER1(x)assert_failure _ ## x

#define ASSER2(x)ASSER1(x)

#define ASSERT(条件)struct ASSER2(__ LINE __){char

assert_failure [(条件)?1:-1];}


主要有效,除非ASSERT在同一条线上使用两次,

或更糟,两次在不同文件中具有相同数字的行(这个

可以

与标题一起出现。


任何更强大的东西,更少的命名空间污染?


TIA,


Francois Grieu

Hi,

I''m using an assert()-like macro to test a constant expression at
compile time

#define ASSERT(condition) struct{char assert_failure[(condition)?
1:-1];}

The idea is that this macro cause a compilation error if a constant
condition
is not true (or if the condition is not constant), with some
(admitedly cryptic)
error message, e.g. "error: size of array `assert_failure'' is
negative".
This works including for expression involving sizeof, and casts
(assuming the compiler is not broken and knows how to perform
arithmetic
as the target system does), for examples

struct { char this, that; } foo;
ASSERT(2 == sizeof foo); // check size of foo

#define LOW8(x) ((unsigned char)(x))
ASSERT(LOW8(0x1A5)==0xA5); // check LOW8 works

int main(void) {return 0;}
This works on several compilers, but <OT>GCC</OTbarks with a warning
on the tune of "unnamed struct/union that defines no instances".

I''m looking for a more portable alternative. Came up with

#define ASSER1(x) assert_failure_##x
#define ASSER2(x) ASSER1(x)
#define ASSERT(condition) struct ASSER2(__LINE__){char
assert_failure[(condition)?1:-1];}

which mostly works, except if ASSERT is used twice on the same line,
or worse, twice at lines with the same number in different files (this
can
occur with headers).

Anything more robust, and less heavy on namespace polution ?

TIA,

Francois Grieu

推荐答案

Francois Grieuaécrit:
Francois Grieu a écrit :




我正在使用一个断言() - 像宏来测试一个常量表达式

编译时间


#define ASSERT(condition)struct {char assert_failure [(condition)?

1:-1];}
Hi,

I''m using an assert()-like macro to test a constant expression at
compile time

#define ASSERT(condition) struct{char assert_failure[(condition)?
1:-1];}



我正在使用接近的东西:


#定义STATIC_ASSERT(tag,cond)\

enum {STATIC_ASSERT__ ## tag = 1 /(cond)}

STATIC_ASSERT(sizeof_long_is_smaller_than_sizeof_v oid_ptr,
sizeof(长)> = sizeof(void *)

);


报告错误如:


...无效枚举

STATIC_ASSERT__sizeof_long_is_smaller_than_sizeof_ void_ptr

枚举确保编译时断言并避免问题

运行时sizeof。


a +,ld。

I am using something close to:

#define STATIC_ASSERT(tag,cond) \
enum { STATIC_ASSERT__ ## tag = 1/(cond) }

STATIC_ASSERT(sizeof_long_is_smaller_than_sizeof_v oid_ptr,
sizeof(long) >= sizeof(void*)
);

which reports errors like:

... invalid enum
STATIC_ASSERT__sizeof_long_is_smaller_than_sizeof_ void_ptr

the enum ensures compile-time assert and avoid the problem with
runtime sizeof.

a+, ld.


文章< fb ******** ******** @ l32g2000hse。 googlegroups.com>,

Francois Grieu< fg **** @ gmail.comwrote:
In article <fb**********************************@l32g2000hse. googlegroups.com>,
Francois Grieu <fg****@gmail.comwrote:

> #define LOW8(x )((unsigned char)(x))
ASSERT(LOW8(0x1A5)== 0xA5); //检查LOW8是否工作
>#define LOW8(x) ((unsigned char)(x))
ASSERT(LOW8(0x1A5)==0xA5); // check LOW8 works



这假设unsigned char恰好有8位,这不是一个很好的假设。如果你想要低8位,为什么不按位使用

和?


我也怀疑你是否真的希望LOW8有一个不同的

类型比x? LOW8(x)的sizeof应该与sizeof x不同,这是不明显的。


如果x是浮动的,你对LOW8的定义也不起作用

点类型,如果x是

a指针,则不一定有用。

-

任何足够先进的错误都与某个功能无法区分。

- Rich Kulawiec

That assumes that unsigned char has exactly 8 bits, which is not
a good assumption. If you want the low 8 bits, why not use
bitwise-and ?

I also question whether you really want LOW8 to have a different
type than x? It is not obvious that sizeof LOW8(x) should be
different than sizeof x .

Your definition of LOW8 also does not work if x is a floating
point type, and is not certain to do anything useful if x is
a pointer.
--
"Any sufficiently advanced bug is indistinguishable from a feature."
-- Rich Kulawiec


Laurent Deniau< La **** ******** @ gmail.com在comp.lang.c中写道:

Laurent Deniau <La************@gmail.comwrote in comp.lang.c:


我正在使用接近的东西:
I am using something close to:



其他人可以发布他们正在使用的编译时断言(又名

静态断言)。


我想比较它们并选择最适合我自己的代码使用。


-
$ b $bTomásó héilidhe


Could other people please post the compile-time asserts they''re using (aka
"static asserts").

I''d like to compare them and pick the best one to use in my own code.

--
Tomás ó héilidhe


这篇关于更可移植的编译时断言()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆