Why the define of ACE_NEW_RETURN use "while(0)"

397 views
Skip to first unread message

风中飘絮

unread,
Jul 20, 2006, 4:51:06 AM7/20/06
to
Hi,Everyone
When I read the source code of ACE.
I can't understand why the define of ACE_NEW_RETURN use "while(0)"?
just in line 157 of the OS_Memory.h

00157 # define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \
00158 do { try { POINTER = new CONSTRUCTOR; } \
00159 catch (ACE_bad_alloc) { errno = ENOMEM; POINTER = 0;
return RET_VAL; } \
00160 } while (0)


Who will be kind enough to tell me that the defference between the
follow codes

00157 # define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \
00158 try { POINTER = new CONSTRUCTOR; } \
00159 catch (ACE_bad_alloc) { errno = ENOMEM; POINTER = 0;
return RET_VAL; } \
00160

Thanks

Douglas C. Schmidt

unread,
Jul 20, 2006, 7:43:48 AM7/20/06
to wuy...@gmail.com, ace-...@cse.wustl.edu
Hi,

> When I read the source code of ACE.

To ensure that we have proper version/platform/compiler information,
please make sure you fill out the appropriate problem report form
(PRF), which is in

$ACE_ROOT/PROBLEM-REPORT-FORM
$TAO_ROOT/PROBLEM-REPORT-FORM

or in

$ACE_ROOT/BUG-REPORT-FORM
$TAO_ROOT/BUG-REPORT-FORM

in older versions of ACE+TAO. Make sure to include this information
when asking any questions about ACE+TAO since otherwise we have to
"guess" what version/platform/compiler/options you've using, which is
error-prone and slows down our responsiveness.

I don't think there is a difference in this case - either the former
or the latter code could be used just fine. If you'd like to enter a
bugzilla entry about this we'll clean it up at some point.

thanks,

Doug
--
Dr. Douglas C. Schmidt Professor and Associate Chair
Electrical Engineering and Computer Science TEL: (615) 343-8197
Vanderbilt University WEB: www.dre.vanderbilt.edu/~schmidt
Nashville, TN 37203 NET: d.sc...@vanderbilt.edu

Stefan Näwe

unread,
Jul 20, 2006, 8:37:34 AM7/20/06
to ace-...@cse.wustl.edu
Douglas C. Schmidt schrieb:

> Hi,
>
>> When I read the source code of ACE.
>
> To ensure that we have proper version/platform/compiler information,
> please make sure you fill out the appropriate problem report form
> (PRF), which is in
>
> $ACE_ROOT/PROBLEM-REPORT-FORM
> $TAO_ROOT/PROBLEM-REPORT-FORM
>
> or in
>
> $ACE_ROOT/BUG-REPORT-FORM
> $TAO_ROOT/BUG-REPORT-FORM
>
> in older versions of ACE+TAO. Make sure to include this information
> when asking any questions about ACE+TAO since otherwise we have to
> "guess" what version/platform/compiler/options you've using, which is
> error-prone and slows down our responsiveness.
>
>> I can't understand why the define of ACE_NEW_RETURN use "while(0)"?
>> just in line 157 of the OS_Memory.h
>>
>> 00157 # define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \
>> 00158 do { try { POINTER = new CONSTRUCTOR; } \
>> 00159 catch (ACE_bad_alloc) { errno = ENOMEM; POINTER = 0;
>> return RET_VAL; } \
>> 00160 } while (0)

This forces you to add an ';':

ACE_NEW_RETURN(p, Foo, -1);

Which will make some editors (e.g. Emacs) happy.

>> Who will be kind enough to tell me that the defference between the
>> follow codes
>>
>> 00157 # define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \
>> 00158 try { POINTER = new CONSTRUCTOR; } \
>> 00159 catch (ACE_bad_alloc) { errno = ENOMEM; POINTER = 0;
>> return RET_VAL; } \
>> 00160
>
> I don't think there is a difference in this case - either the former
> or the latter code could be used just fine. If you'd like to enter a
> bugzilla entry about this we'll clean it up at some point.
>
> thanks,
>
> Doug


Stefan
--
----------------------------------------------------------------------
Stefan Naewe ATLAS Elektronik GmbH
Dept.: NUS T4
phone: +49-(0)421-457-1378 Sebaldsbruecker Heerstr. 235
fax: +49-(0)421-457-3913 28305 Bremen

J.T. Conklin

unread,
Jul 20, 2006, 9:26:37 AM7/20/06
to Douglas C. Schmidt, ace-...@cse.wustl.edu, wuy...@gmail.com
Hi Dr. Schmidt,

sch...@dre.vanderbilt.edu (Douglas C. Schmidt) writes:
>> I can't understand why the define of ACE_NEW_RETURN use "while(0)"?
>> just in line 157 of the OS_Memory.h
>>
>>00157 # define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \
>>00158 do { try { POINTER = new CONSTRUCTOR; } \
>>00159 catch (ACE_bad_alloc) { errno = ENOMEM; POINTER = 0;
>>return RET_VAL; } \
>>00160 } while (0)
>>
>>

>>Who will be kind enough to tell me that the defference between the
>>follow codes
>>
>>00157 # define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \
>>00158 try { POINTER = new CONSTRUCTOR; } \
>>00159 catch (ACE_bad_alloc) { errno = ENOMEM; POINTER = 0;
>>return RET_VAL; } \
>>00160
>
> I don't think there is a difference in this case - either the former
> or the latter code could be used just fine. If you'd like to enter a
> bugzilla entry about this we'll clean it up at some point.

While in this particular case, the do-while(0) is unnecessary, it is
the general idiom we use to ensure "function-like" macros expand to a
single statement.

IMO, It seems more desirable for us to use the idiom consistantly,
even in the cases where it's not strictly necessary, than it would be
to "clean up" those that don't need it. Because if sometime down the
road someone adds another statement to one of these cases and forgets
to add the do-while(0) wrapper, it would be easy to introduce hard to
find bugs in our users code.

But if someone decides that this is important, I'd claim that it
should be done across the board instead of as each macro is encountered.
That's a pretty big task, not one to be taken up lightly.

--jtc

--
J.T. Conklin

Douglas C. Schmidt

unread,
Jul 20, 2006, 10:35:13 AM7/20/06
to j...@acorntoolworks.com, ace-...@cse.wustl.edu, wuy...@gmail.com

Hi J.T.,

> >>Who will be kind enough to tell me that the defference between the
> >>follow codes
> >>
> >>00157 # define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \
> >>00158 try { POINTER = new CONSTRUCTOR; } \
> >>00159 catch (ACE_bad_alloc) { errno = ENOMEM; POINTER = 0;
> >>return RET_VAL; } \
> >>00160
> >
> > I don't think there is a difference in this case - either the former
> > or the latter code could be used just fine. If you'd like to enter a
> > bugzilla entry about this we'll clean it up at some point.
>
> While in this particular case, the do-while(0) is unnecessary, it is
> the general idiom we use to ensure "function-like" macros expand to a
> single statement.

BTW, I looked into this a bit more and we need the do/while(0) even for
the try/catch case. Here's a small example that illustrates why:

----------------------------------------

int main ()
{
if (10 > 20)
try {
}
catch (...) {
}; // Compile error if the ';' is here!
else
;
return 0;
}

----------------------------------------

Whereas this works fine:

----------------------------------------

int main ()
{
if (10 > 20)
do
{
try {
}
catch (...) {
}
} while (0); // It's fine to have the ';' here.
else
;
return 0;
}

----------------------------------------

> IMO, It seems more desirable for us to use the idiom consistantly,
> even in the cases where it's not strictly necessary, than it would be
> to "clean up" those that don't need it. Because if sometime down the
> road someone adds another statement to one of these cases and forgets
> to add the do-while(0) wrapper, it would be easy to introduce hard to
> find bugs in our users code.
>
> But if someone decides that this is important, I'd claim that it
> should be done across the board instead of as each macro is encountered.
> That's a pretty big task, not one to be taken up lightly.

Right, and in this case it's essential!

Thanks,

Doug

avi...@gmail.com

unread,
Oct 3, 2017, 1:20:29 PM10/3/17
to
Hi can anyone help me to know
does any memory get allocated in ACE_NEW_RETURN. If yes then where we are freeing it. Explain me why it is needed to allocate memory in ACE_NEW_RETURN.What is purpose of ACE_NEW_RETURN.

Andreas Leitgeb

unread,
Oct 3, 2017, 2:00:51 PM10/3/17
to
avi...@gmail.com <avi...@gmail.com> wrote:
>> 00157 # define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \
>> 00158 do { try { POINTER = new CONSTRUCTOR; } \
>> 00159 catch (ACE_bad_alloc) { errno = ENOMEM; POINTER = 0;
>> return RET_VAL; } \
>> 00160 } while (0)

> Hi can anyone help me to know
> does any memory get allocated in ACE_NEW_RETURN. If yes then where
> we are freeing it. Explain me why it is needed to allocate memory
> in ACE_NEW_RETURN.What is purpose of ACE_NEW_RETURN.

Allocation of memory happens in "POINTER = new CONSTRUCTOR;" (where
CONSTRUCTOR will be replaced by some actual class name and its con-
struction arguments (possibly none) in parentheses (always needed)
and POINTER will be replaced by an actual pointer variable. Both are
provided as arguments to the macro, as well as an return-value to
be returned from current function in case of allocation failure.

Obviously, the memory is not immediately freed within the macro, but
only "after use" somewhere else (and not even always at the same place
where the macro was used).

Reply all
Reply to author
Forward
0 new messages