Article View: comp.lang.c.moderated
Article #2482Re: Interesting compile-time assertion macro
From: Thad Smith
Date: Wed, 03 Apr 1996 13:12
Date: Wed, 03 Apr 1996 13:12
60 lines
2935 bytes
2935 bytes
In article <4jq1lg$a67@solutions.solon.com>,
Mike Coffman <coffman@cat.com> wrote:
>Mike Haertel wrote in comp.lang.c.moderated:
>> So I came up with a compile-time equivalent of <assert.h>:
>>
>> /*
>> * Cause a compile-time error if the asserted expression, which
>> * must be a constant expression according to the rules of ANSI C,
>> * is false. Each use of this macro must supply a different
>> * identifier for KEY.
>> *
>> * It works by trying to declare an array of negative size if
>> * the asserted expression is false.
>> */
>> #define ASSERT_COMPILE_TIME(EXPR, KEY) \
>> struct ASSERT_COMPILE_TIME_##KEY { \
>> char ASSERT_COMPILE_TIME_##KEY[2*((EXPR) != 0) - 1]; \
>> }
>
>Mike:
>I like the principle of protecting the users of source code that I write
>from the mistakes they make adjusting the parameters to their
>application.
>I usually use the sequence:
>
>#if test_condition
>#error error message
>#endif
>
>but, as you can see, this takes three lines to invoke to your one.
The other problem is that the preprocessor doesn't have access to the
full power of constant expressions invoving sizeof, offsetof, etc.
I found Mike Haertel's macro clever and inspiring. I suggested in
email that the struct name could be omitted, so that the KEY
parameter isn't required. He responded that the gcc produced a
warning for such a declaration. I have put together a version which
concatenates __LINE__ to a symbol to make it unique:
/* ASSERT_COMPILE_TIME() allows a constant expression to be evaluated
** at compile time. It causes an error, due to negative array size,
** if the expression is false. It must be placed where declarations
** are allowed.
** Adapted from posting 1 Apr 1996 in comp.lang.c.moderated by
** haertel@ichips.intel.com (Mike Haertel).
*/
#define ASSERT_CAT1(x) ASSERT_CAT ## x
#define ASSERT_CAT0(x) ASSERT_CAT1(x)
#define ASSERT_COMPILE_TIME(expr) \
struct ASSERT_CAT0(__LINE__){char t[2*!!(expr)-1];}
>The only overhead/disadvantage to your technique is that once I get my
>code to compile successfully I have a number of structures composed of
>one element character arrays taking up a little space.
Not really. A struct is defined, but not declared, i.e., there is no
struct variable so no space is taken. :-)
Thad
Technical Details
Message-ID:
<4jttgb$3n3@solutions.solon.com>Path:
arc1-ca.pugleaf.net!solon.com!not-for-mailReferences:
<4jol55$1pi@solutions.solon.com> <4jq1lg$a67@solutions.solon.com>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!solon.com!not-for-mail From: thads@csn.net (Thad Smith) Newsgroups: comp.lang.c.moderated Subject: Re: Interesting compile-time assertion macro Date: 3 Apr 1996 07:12:43 -0600 Organization: T3 Systems Sender: clc@solutions.solon.com Approved: clc@solutions.solon.com Message-ID: <4jttgb$3n3@solutions.solon.com> References: <4jol55$1pi@solutions.solon.com> <4jq1lg$a67@solutions.solon.com> Reply-To: ThadSmith@acm.org NNTP-Posting-Host: solutions.solon.com