Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Understanding assert code

Reply
Thread Tools

Understanding assert code

 
 
Sami
Guest
Posts: n/a
 
      11-05-2010
Hi

I am using some C code with the following macro:

#define __force_assert(x) ((assert)(x))

Can anyone explain what is going on here.

Thanks.
 
Reply With Quote
 
 
 
 
Ben Pfaff
Guest
Posts: n/a
 
      11-05-2010
Sami <(E-Mail Removed)> writes:

> I am using some C code with the following macro:
>
> #define __force_assert(x) ((assert)(x))


This will invoke a function named assert, ignoring any
function-like macro of the same name.

That's puzzling. The C standard says that assert is a macro. It
doesn't say anything about an assert function. I don't know
anyone would want to do this.
--
Ben Pfaff
http://benpfaff.org
 
Reply With Quote
 
 
 
 
Seebs
Guest
Posts: n/a
 
      11-05-2010
On 2010-11-05, Sami <(E-Mail Removed)> wrote:
> Hi
>
> I am using some C code with the following macro:
>
> #define __force_assert(x) ((assert)(x))
>
> Can anyone explain what is going on here.


Someone is trying to be clever.

assert(x) aborts if x is untrue... Sometimes.

If you #define the symbol NDEBUG before including <assert.h>,
assert(x) is a no-op.

Now, since this is happening in the preprocessor, Our Protagonist
has concluded that obviously, this is done by re-defining the
name "assert", which is presumably a function-like macro. (He's
probably right; in particular, it can't be a non-function-like macro,
I don't think, because so far as I can tell you're allowed to have
a variable named that, though it might be unwise.)

So he's using (assert) to try to force the compiler to generate
an actual call to the assert() function rather than macroing it
away. This might work, because function-like-macros are only
expanded when the next thing after the macro name is a left
parens. Instead, he's arranged for it to be a right parens.

I would never do this.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / http://www.velocityreviews.com/forums/(E-Mail Removed)
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      11-05-2010
Ben Pfaff <(E-Mail Removed)> writes:
> Sami <(E-Mail Removed)> writes:
>> I am using some C code with the following macro:
>>
>> #define __force_assert(x) ((assert)(x))

>
> This will invoke a function named assert, ignoring any
> function-like macro of the same name.
>
> That's puzzling. The C standard says that assert is a macro. It
> doesn't say anything about an assert function. I don't know
> anyone would want to do this.


I suppose someone (not the C implementation) might provide a function
called "assert", but that would be a silly thing to do.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      11-05-2010
Kenneth Brody <(E-Mail Removed)> writes:
> On 11/5/2010 2:40 PM, Keith Thompson wrote:
>> Ben Pfaff<(E-Mail Removed)> writes:
>>> Sami<(E-Mail Removed)> writes:
>>>> I am using some C code with the following macro:
>>>>
>>>> #define __force_assert(x) ((assert)(x))
>>>
>>> This will invoke a function named assert, ignoring any
>>> function-like macro of the same name.
>>>
>>> That's puzzling. The C standard says that assert is a macro. It
>>> doesn't say anything about an assert function. I don't know
>>> anyone would want to do this.

>>
>> I suppose someone (not the C implementation) might provide a function
>> called "assert", but that would be a silly thing to do.

>
> Well, the assert() macro becomes a no-op if NDEBUG is #defined. It appears
> that this implementation has created __force_assert() which remains in
> effect even in the presence of NDEBUG.


The OP didn't say that the implementation created it.

If it is part of the implementation, it might actually be reasonable;
it could be a way to provide something that acts like the standard
assert() macro but that isn't affected by NDEBUG.

If it's not part of the implementation, then the use of a reserved
name starting with "__" is ill-advised, as is the assumption that
there's an actual function called "assert".

Also, an actual function can't produce a message containing the text
of the argument and the values of __FILE__, __LINE__, and __func__.

Sami, where did you see this? Is it part of a program, or is it
in a header provided by the implementation?

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Sami
Guest
Posts: n/a
 
      11-06-2010
Keith Thompson writes:

> Kenneth Brody <(E-Mail Removed)> writes:
>> On 11/5/2010 2:40 PM, Keith Thompson wrote:
>>> Ben Pfaff<(E-Mail Removed)> writes:
>>>> Sami<(E-Mail Removed)> writes:
>>>>> I am using some C code with the following macro:
>>>>>
>>>>> #define __force_assert(x) ((assert)(x))
>>>>
>>>> This will invoke a function named assert, ignoring any function-like
>>>> macro of the same name.
>>>>
>>>> That's puzzling. The C standard says that assert is a macro. It
>>>> doesn't say anything about an assert function. I don't know anyone
>>>> would want to do this.
>>>
>>> I suppose someone (not the C implementation) might provide a function
>>> called "assert", but that would be a silly thing to do.

>>
>> Well, the assert() macro becomes a no-op if NDEBUG is #defined. It
>> appears that this implementation has created __force_assert() which
>> remains in effect even in the presence of NDEBUG.

>
> The OP didn't say that the implementation created it.
>
> If it is part of the implementation, it might actually be reasonable; it
> could be a way to provide something that acts like the standard assert()
> macro but that isn't affected by NDEBUG.
>
> If it's not part of the implementation, then the use of a reserved name
> starting with "__" is ill-advised, as is the assumption that there's an
> actual function called "assert".
>
> Also, an actual function can't produce a message containing the text of
> the argument and the values of __FILE__, __LINE__, and __func__.
>
> Sami, where did you see this? Is it part of a program, or is it in a
> header provided by the implementation?


Hi Kieth,

The codebase I'm working on has a couple of executables and a shared DLL.
One of the headers in this DLL provides __force_assert.

An example of how it's used in the code is:

char * fname_new = strdup(fname);
__force_assert( fname_new != NULL );

Most functions and macros in the DLL have a __ prefix, I guess to avoid
polluting the executable's "namespace".
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      11-06-2010
Sami <(E-Mail Removed)> writes:
> Keith Thompson writes:

[...]
>>>>> Sami<(E-Mail Removed)> writes:
>>>>>> I am using some C code with the following macro:
>>>>>>
>>>>>> #define __force_assert(x) ((assert)(x))

[...]
>> Sami, where did you see this? Is it part of a program, or is it in a
>> header provided by the implementation?

>
> Hi Kieth,


It's "Keith".

> The codebase I'm working on has a couple of executables and a shared DLL.
> One of the headers in this DLL provides __force_assert.
>
> An example of how it's used in the code is:
>
> char * fname_new = strdup(fname);
> __force_assert( fname_new != NULL );


Where is the "assert" function declared or defined? The standard C
header <assert.h> defines a *macro* called "assert"; it doesn't declare
a function by that name. On the implementation I use, there is no
assert() function; this:
#include <assert.h>
...
assert(0);
fails to compile.

> Most functions and macros in the DLL have a __ prefix, I guess to avoid
> polluting the executable's "namespace".


That's a bad idea. Rather than polluting the executable's namespace,
it's polluting the implementation's namespace.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Ben Pfaff
Guest
Posts: n/a
 
      11-06-2010
Keith Thompson <(E-Mail Removed)> writes:

> Where is the "assert" function declared or defined? The standard C
> header <assert.h> defines a *macro* called "assert"; it doesn't declare
> a function by that name. On the implementation I use, there is no
> assert() function; this:
> #include <assert.h>
> ...
> assert(0);
> fails to compile.


Why? (I'm assuming that you actually put that statement inside a
function body.)
--
Ben Pfaff
http://benpfaff.org
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      11-06-2010
Ben Pfaff <(E-Mail Removed)> writes:
> Keith Thompson <(E-Mail Removed)> writes:
>> Where is the "assert" function declared or defined? The standard C
>> header <assert.h> defines a *macro* called "assert"; it doesn't declare
>> a function by that name. On the implementation I use, there is no
>> assert() function; this:
>> #include <assert.h>
>> ...
>> assert(0);
>> fails to compile.

>
> Why? (I'm assuming that you actually put that statement inside a
> function body.)


Because, rather than following the advice I give several times a
week to copy-and-paste actual code rather than paraphrasing it by
re-typing it, I paraphrased the actual code by re-typing it and
got it wrong in a way that destroyed the point I was trying to make.

Here's the actual code:

#include <assert.h>
int main(void) {
(assert)(0);
return 0;
}

And here are the error messages from the compiler:

c.c: In function ‘main’:
c.c:3: error: ‘assert’ undeclared (first use in this function)
c.c:3: error: (Each undeclared identifier is reported only once
c.c:3: error: for each function it appears in.)

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      11-06-2010
On 11/6/2010 5:06 PM, Keith Thompson wrote:
> Ben Pfaff<(E-Mail Removed)> writes:
>> Keith Thompson<(E-Mail Removed)> writes:
>>> Where is the "assert" function declared or defined? The standard C
>>> header<assert.h> defines a *macro* called "assert"; it doesn't declare
>>> a function by that name. On the implementation I use, there is no
>>> assert() function; this:
>>> #include<assert.h>
>>> ...
>>> assert(0);
>>> fails to compile.

>>
>> Why? (I'm assuming that you actually put that statement inside a
>> function body.)

>
> Because, rather than following the advice I give several times a
> week to copy-and-paste actual code rather than paraphrasing it by
> re-typing it, I paraphrased the actual code by re-typing it and
> got it wrong in a way that destroyed the point I was trying to make.
>
> Here's the actual code:
>
> #include<assert.h>
> int main(void) {
> (assert)(0);
> return 0;
> }
>
> And here are the error messages from the compiler:
>
> c.c: In function ‘main’:
> c.c:3: error: ‘assert’ undeclared (first use in this function)
> c.c:3: error: (Each undeclared identifier is reported only once
> c.c:3: error: for each function it appears in.)


Interestingly, the diagnostic is not required. Quoth the
Standard: "If the macro definition is suppressed in order to access
an actual function, the behavior is undefined," and "undefined"
includes the possibility that no diagnostic appears, that the code
compiles, and that any oddities happen at run-time.

It seems to me that the authors of the macro (reproduced here
for reference):

#define __force_assert(x) ((assert)(x))

.... were trying to be responsible citizens, but didn't quite think
things through. If an implementation's assert() macro actually
generates a call on an assert() helper function (which it may), this
__force_assert() macro necessarily generates an incorrect call. (Of
course, the assert() implementation might be magical -- but in that
case, the __force_assert() kludge is on even thinner ice!)

--
Eric Sosman
(E-Mail Removed)lid
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
To assert or not to assert... ImpalerCore C Programming 79 05-17-2010 12:47 PM
Understanding Assert and Exceptions mailforpr@googlemail.com C++ 29 10-17-2006 02:12 PM
assert 0, "foo" vs. assert(0, "foo") Thomas Guettler Python 3 02-23-2005 07:53 PM
assert(x) and '#define ASSERT(x) assert(x)' Alex Vinokur C Programming 5 11-25-2004 08:48 PM
RE: remove assert statement (Was: Re: PEP new assert idiom) Robert Brewer Python 1 11-07-2004 06:53 PM



Advertisments