473,765 Members | 2,061 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

more portable compile-time assert()

Hi,

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

#define ASSERT(conditio n) 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(0x1 A5)==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(conditio n) 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
Jan 11 '08 #1
11 9220
Francois Grieu a écrit :
Hi,

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

#define ASSERT(conditio n) struct{char assert_failure[(condition)?
1:-1];}
I am using something close to:

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

STATIC_ASSERT(s izeof_long_is_s maller_than_siz eof_void_ptr,
sizeof(long) >= sizeof(void*)
);

which reports errors like:

... invalid enum
STATIC_ASSERT__ sizeof_long_is_ smaller_than_si zeof_void_ptr

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

a+, ld.
Jan 11 '08 #2
In article <fb************ *************** *******@l32g200 0hse.googlegrou ps.com>,
Francois Grieu <fg****@gmail.c omwrote:
>#define LOW8(x) ((unsigned char)(x))
ASSERT(LOW8(0x 1A5)==0xA5); // check LOW8 works
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 indistinguishab le from a feature."
-- Rich Kulawiec
Jan 11 '08 #3
Laurent Deniau <La************ @gmail.comwrote in comp.lang.c:

I am using something close to:

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
Jan 11 '08 #4
On Jan 11, 6:09 pm, rober...@ibd.nr c-cnrc.gc.ca (Walter Roberson)
wrote:
In article <fb744b46-cbad-4ac0-8822-624e180a0...@l3 2g2000hse.googl egroups.com>,
Francois Grieu <fgr...@gmail.c omwrote:
#define LOW8(x) ((unsigned char)(x))
ASSERT(LOW8(0x1 A5)==0xA5); // check LOW8 works

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 ?
<OTmany compilers generate much better code for a cast to unsigned
char than for a bitwise AND. </OT>

An alternative might be

#include <limits.h>

// LOW8(x) efficiently casts x to unsigned char and
// keeps only the low 8 bits; result is an unsigned char
#if UCHAR_MAX==0xFF
#define LOW8(x) ((unsigned char)(x))
#else
#define LOW8(x) ((unsigned char)((unsigned char)(x)&0xFF))
#endif
ASSERT( // check LOW8 works
LOW8(0x1A5)==0x A5 &&
LOW8(0)==0 &&
LOW8(0x80)>=0 &&
LOW8(-1)>=0 &&
1==sizeof LOW8(0x12345678 ) &&
1==sizeof LOW8(1.)
);
Jan 11 '08 #5

"Tomás Ó hÉilidhe" <to*@lavabit.co mwrote in message
>
Could other people please post the compile-time asserts they're using (aka
"static asserts").
This is basically your method for picking up compile time faults.

#if condition
#error "condition was true"
#endif

There are subtle problems with it because the #if condition is expanded by
the preprocessor, not the compiler itself, but it is the standard facility
provided and you should use it.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
Jan 11 '08 #6
In article <Ac************ *********@bt.co m>,
Malcolm McLean <re*******@btin ternet.comwrote :
>"Tomás Ó hÉilidhe" <to*@lavabit.co mwrote in message
>Could other people please post the compile-time asserts they're using (aka
"static asserts").
>This is basically your method for picking up compile time faults.
>#if condition
#error "condition was true"
#endif
>There are subtle problems with it because the #if condition is expanded by
the preprocessor, not the compiler itself, but it is the standard facility
provided and you should use it.
Unfortunately the preprocessor will not evaluate sizeof()
(or at least not and get the sizes that would be generated at compile time!)
--
"I will speculate that [...] applications [...] could actually see a
performance boost for most users by going dual-core [...] because it
is running the adware and spyware that [...] are otherwise slowing
down the single CPU that user has today" -- Herb Sutter
Jan 11 '08 #7
"Tomï¿½ï¿½ï¿½ï¿ ½ï¿½ï¿½ï¿½ï¿½ï¿ ½ï¿½ï¿½ï¿½ï¿½ï¿ ½ï¿½ï¿½ï¿½ï¿½ï¿ ½ï¿½ï¿½ï¿½ï¿½ï¿ ½ï¿½ï¿½ï¿½ï¿½ï¿ ½ï¿½ï¿½ï¿½" wrote:
Laurent Deniau <La************ @gmail.comwrote in comp.lang.c:

>I am using something close to:

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.
It's been discussed here some time ago; here it is again:
#define ASSERT(conditio n) \
extern char dummy_assert_ar ray[(condition)?1:-1]

and e.g. to make portability issues stand out,
ASSERT(sizeof(i nt)==sizeof(lon g));

--
Ark

Jan 12 '08 #8
On Jan 11, 11:14 am, "Tomás Ó hÉilidhe" <t...@lavabit.c omwrote:
Laurent Deniau <Laurent.Den... @gmail.comwrote in comp.lang.c:
I am using something close to:

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.
I recently started using something along these lines (influenced from
somewhere, but not sure where off-hand):
#define ASSERT_NAME(nam e, cond) \
do { \
typedef int name ## _assertion_fail ed[(int)(cond) * 2 - 1]; \
} while (0)

I personally like using a "name" argument to the macro to avoid
collisions when using __LINE__.
Jan 13 '08 #9
Justin Spahr-Summers wrote:
I recently started using something along these lines (influenced from
somewhere, but not sure where off-hand):
#define ASSERT_NAME(nam e, cond) \
do { \
typedef int name ## _assertion_fail ed[(int)(cond) * 2 - 1]; \
} while (0)

I personally like using a "name" argument to the macro to avoid
collisions when using __LINE__.
Suggestions:
1 - Remove spurious "do{" and ";}while(0) ". Then you'd be able to use
ASSERT_NAME outside of any block, where "compile-time asserts" ought to be.
2 - There is still a small chance of name collision; to avoid it safely
and forever, replace "typedef" with "extern"
3 - If #2 is done, you no longer need the "name" argument, which fact
simplifies the matters.
Hmmm... After all these are done, what remains is effectively the same
as I posted elsethread.
--
Ark
Jan 13 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

28
2721
by: lovecreatesbeauty | last post by:
On gcc, which version of C standard has the most compliant: -c89, -ansi or c99? For more portable C code, which options should be applied to compilation? Can the following options guarantee the most portable C code for different environment? gcc -ansi -pedantic -Wall test.c
2
1371
by: octangle | last post by:
Create enumerated values using the three highest bits as bit flags that define comparison operators. VERSION A: ---------- enum eCriteria { eCriteriaOne = 1, eCriteriaTwo = 2,
0
9568
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9404
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
1
9959
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8833
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7381
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6651
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
1
3929
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3532
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2806
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.