Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > function argument evaluation order and asserts and macros

Reply
Thread Tools

function argument evaluation order and asserts and macros

 
 
jacek.dziedzic@gmail.com
Guest
Posts: n/a
 
      09-24-2008
Hi!

I am for defensive programming and am working on a code stuffed with
quite a lot of assert-like statements, like

Asserts(pos[i]==pos[i],"Position #"+to_string(i)+" is NaN");

where Asserts is

#define Asserts(expr,s) \
if(!(expr))
Framework::Asserts_Fail(__STRING(expr),__FILE__,__ LINE__,__PRETTY_FUNCTION__,s)

and Asserts_Fail() displays a bunch of info and terminates the
program.

My question: a typical assert falls through 99.999% of the time as
if(!(expr)) is false. Am I guaranteed though, that the std::string
"Position #number is NaN" would not be constructed in vain _every
time_ this assert is checked? My understanding is that since this is a
macro, not a function call, then it is only constructed when the
assert actually clicks and Asserts_Fail() is called. If Asserts() was
made to be a function call instead of a macro, then I might not be as
lucky.

Can anyone confirm or contradict this?

TIA,
- J.
 
Reply With Quote
 
 
 
 
Pascal J. Bourguignon
Guest
Posts: n/a
 
      09-24-2008
writes:

> Hi!
>
> I am for defensive programming and am working on a code stuffed with
> quite a lot of assert-like statements, like
>
> Asserts(pos[i]==pos[i],"Position #"+to_string(i)+" is NaN");
>
> where Asserts is
>
> #define Asserts(expr,s) \
> if(!(expr))
> Framework::Asserts_Fail(__STRING(expr),__FILE__,__ LINE__,__PRETTY_FUNCTION__,s)
>
> and Asserts_Fail() displays a bunch of info and terminates the
> program.
>
> My question: a typical assert falls through 99.999% of the time as
> if(!(expr)) is false. Am I guaranteed though, that the std::string
> "Position #number is NaN" would not be constructed in vain _every
> time_ this assert is checked? My understanding is that since this is a
> macro, not a function call, then it is only constructed when the
> assert actually clicks and Asserts_Fail() is called. If Asserts() was
> made to be a function call instead of a macro, then I might not be as
> lucky.
>
> Can anyone confirm or contradict this?


Yes, emacs can.


Put your source in some buffer named test.c:
------------------------------------------------------------------------
#define Asserts(expr,s) \
if(!(expr)) Framework::Asserts_Fail(__STRING(expr),__FILE__,__ LINE__,__PRETTY_FUNCTION__,s)


Asserts(pos[i]==pos[i],"Position #"+to_string(i)+" is NaN");
------------------------------------------------------------------------

Select it and type C-x C-e ; it will open another buffer containing
the code with the macros expanded:
------------------------------------------------------------------------




if(!(pos[i]==pos[i])) Framework::Asserts_Fail(__STRING(pos[i]==pos[i]),"a.c",5,__PRETTY_FUNCTION__,"Position #"+to_string(i)+" is NaN");
------------------------------------------------------------------------

If you don't have emacs, you can run the c preprocessor on the source:

gcc -E -o test.e test.c && cat test.e


So you can see that indeed, the expansion of the macro is purely
textual, and the the concatenation will occur only when the assertion
is false.

--
__Pascal Bourguignon__
 
Reply With Quote
 
 
 
 
James Kanze
Guest
Posts: n/a
 
      09-24-2008
On Sep 24, 9:45 am, jacek.dzied...@gmail.com wrote:

> I am for defensive programming and am working on a code
> stuffed with quite a lot of assert-like statements, like


> Asserts(pos[i]==pos[i],"Position #"+to_string(i)+" is NaN");


> where Asserts is


> #define Asserts(expr,s) \
> if(!(expr))
> Framework::Asserts_Fail(__STRING(expr),__FILE__,__ LINE__,__PRETTY_FUNCTION__,s)


> and Asserts_Fail() displays a bunch of info and terminates the
> program.


That's a very unusual definition. I've generally seen something
more like:

((expr) || Framework::Asserts_Fail( ... ))

The idea being that the expansion of the macro is a pure
expression, and can be used anywhere an expression can be used
(and if there is support for turning it off, the macro expands
to something like "((void)0)").

> My question: a typical assert falls through 99.999% of the time as
> if(!(expr)) is false.


More often than that, one would hope. In production code, it
should fall through 100% of the time.

> Am I guaranteed though, that the std::string "Position #number
> is NaN" would not be constructed in vain _every time_ this
> assert is checked?


Obviously. With both versions above. Including if the macro
was passed a string expression.

> My understanding is that since this is a macro, not a function
> call, then it is only constructed when the assert actually
> clicks and Asserts_Fail() is called. If Asserts() was made to
> be a function call instead of a macro, then I might not be as
> lucky.


> Can anyone confirm or contradict this?


Macros are, well, macros. They are expanded textually by the
compiler. What happens after that depends on the results of the
textual expansion.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

 
Reply With Quote
 
jacek.dziedzic@gmail.com
Guest
Posts: n/a
 
      09-24-2008
On Sep 24, 10:42*am, p...@informatimago.com (Pascal J. Bourguignon)
wrote:
> So you can see that indeed, the expansion of the macro is purely
> textual, and the the concatenation will occur only when the assertion
> is false.


Thank you.
 
Reply With Quote
 
jacek.dziedzic@gmail.com
Guest
Posts: n/a
 
      09-24-2008
On Sep 24, 11:06*am, James Kanze <james.ka...@gmail.com> wrote:
> That's a very unusual definition. *I've generally seen something
> more like:


Yes, I rolled my own without seeing how it's typically done.

>
> * * ((expr) || Framework::Asserts_Fail( ... ))
>
> The idea being that the expansion of the macro is a pure
> expression, and can be used anywhere an expression can be used
> (and if there is support for turning it off, the macro expands
> to something like "((void)0)").


Yes, I can see the advantage.

> > My question: a typical assert falls through 99.999% of the time as
> > if(!(expr)) is false.

>
> More often than that, one would hope. *In production code, it
> should fall through 100% of the time.


I'm very far from production code .

> Macros are, well, macros. *They are expanded textually by the
> compiler. *What happens after that depends on the results of the
> textual expansion.


Right, thanks for the confirmation.
 
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
Variable argument function as a parameter of a variable argument function AikidoGuy C Programming 11 11-21-2011 10:43 PM
function argument dependent on another function argument? Reckoner Python 11 01-19-2009 03:31 AM
Macros within function-like macros? Anthony de Almeida Lopes C Programming 13 12-27-2005 08:38 PM
Explanation of macros; Haskell macros mike420@ziplip.com Python 80 11-07-2003 02:22 AM
Re: Explanation of macros; Haskell macros mike420@ziplip.com Python 1 10-07-2003 04:07 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57