Two things I'd like to see in C++ 2009

J

J. Smith

I know about RAII and BS's response to previous requests, but I'd really
love to see 'finally' available in C++ exception handling. Yes, we can
live without 'finally' but it means a bit more typing (more classes) for
simple scenarios (like calling LeaveCriticalSection() before a function
returns). It would also make porting other languages to C++ a bit more
simple.

Another thing I'd like to see is a 'reentrant' keyword that can be
applied to functions and methods. The compiler should have all the info
necessary to complain when a non-reentrant function is labeled as reentrant.
 
J

Joe Seigh

J. Smith said:
Another thing I'd like to see is a 'reentrant' keyword that can be
applied to functions and methods. The compiler should have all the info
necessary to complain when a non-reentrant function is labeled as
reentrant.

So how would the compiler identify a non-reentrant function?
 
M

Mercator

J. Smith said:
I know about RAII and BS's response to previous requests, but I'd really
love to see 'finally' available in C++ exception handling.

You probably don't know (enough) about RAII. Otherwise you wouldn't
want a 'finally'.
 
V

verec

It uses no static or global variables.

.... And only calls functions themselves labelled as "reentrant" ...
.... And doesn't dereference any pointer ...

file super_safe.cpp

void f(int *p) reentrant {
*p = 0 ;
}


file subvert_it_anyway.cpp

int global ;
int main() {
f(&global) ;
return 0 ;
}
But a new keyword is 'disproportionate'.

.... or the idea, itself, inappropriate ? :)
but I'd really
love to see 'finally' available in C++ exception handling.

That one seems more readily implementable, but C++ politics will
probably vote it down :(
 
V

verec

You probably don't know (enough) about RAII. Otherwise you wouldn't
want a 'finally'.

You probably don't know (enough) about finally. Otherwise you would
see RAII as just a special hackish case of the more general finally
construct.
 
B

benben

You probably don't know (enough) about finally. Otherwise you would
see RAII as just a special hackish case of the more general finally
construct.

Ok, fair to say, RAII binds to class, and finally block binds to procedure.
If you are lazy designing proper classes, you'd want finally. If you are
doing a huge project, where a lot of classes and procedures are concerned,
binding to classes is instantaneous.

Regards,
Ben
 
V

verec

Ok, fair to say, RAII binds to class, and finally block binds to procedure.
If you are lazy designing proper classes, you'd want finally. If you are
doing a huge project, where a lot of classes and procedures are concerned,
binding to classes is instantaneous.

How so ?!?! Instantenous????

in a finally block, you only have to clean-up whatever it is
that needs cleaning, whether _you_ acquired it or not.

With RAII, not only do you _have to_ define extra classes, but
also cope with the communication between the point you're about
to (re) throw and the said class(es) to deal with the case that
the "resource" that wasn't for you to acquire in the first place,
nor to release in nornal circumstances, are for you to release
in the exceptional case.
 
B

benben

verec said:
How so ?!?! Instantenous????

in a finally block, you only have to clean-up whatever it is
that needs cleaning, whether _you_ acquired it or not.

With RAII, not only do you _have to_ define extra classes, but
also cope with the communication between the point you're about
to (re) throw and the said class(es) to deal with the case that
the "resource" that wasn't for you to acquire in the first place,
nor to release in nornal circumstances, are for you to release
in the exceptional case.

With good design, all clean ups are affiliated with a class.

Let's say we have a huge project in which finally blocks are intensively
used. Class A is one of many classes the project consists of. Now you are
asked to update A's implementation and the change requires a differently
clean up scheme. You now face a large number of finally blocks needed to be
rewritten.

On the other hand, had all the necessary clean up operations encapsulated by
class A, we only have to update the clean up code once, inside A. RAII will
take care of everything else.

Regards,
Ben
 
M

Mercator

benben said:
On the other hand, had all the necessary clean up operations encapsulated by
class A, we only have to update the clean up code once, inside A. RAII will
take care of everything else.

That's the point! Do it once vs. do it all the time (and forget it or
do it wrong sometimes). BTW, look at Java programs. If there is a
function with 2 ore more resources to be cleaned up people often
(mostly?) write code that isn't 100% correct (sometimes you even need
to write a try/catch within the finally).
 
M

Mercator

verec said:
... And only calls functions themselves labelled as "reentrant" ...

Good point.
... And doesn't dereference any pointer ...

I'm not sure. Otherwise not even strcpy would be 'reentrant'.
file super_safe.cpp

void f(int *p) reentrant {
*p = 0 ;
}


file subvert_it_anyway.cpp

int global ;
int main() {
f(&global) ;
return 0 ;
}


... or the idea, itself, inappropriate ? :)

Yes, a function should not care whether the _user_ passes a global or
not. That clearly shifts responsibilities to the wrong place. BTW,
'reentrant' is defined by POSIX, e.g.
http://www.unix.org/whitepapers/reentrant.html#tag_foot_1
 
P

Peter Koch Larsen

verec said:
You probably don't know (enough) about finally. Otherwise you would
see RAII as just a special hackish case of the more general finally
construct.
That is certainly false. RAII is needed to ensure proper, automatic and
deterministic deallocation of your resources. finally is an errorprone hack
for languages that do not have RAII and it forces the user of the class to
be aware of whether RAII for every class is needed (and to change his code
if the class goes from a non-resource state to one where it has resources),
and it requires the programmer to write extra code every time he uses a
resource.

/Peter
 
V

verec

With good design, all clean ups are affiliated with a class.

Well, in my world, I cannot even come close to the requirement that
I control 100% of the system. From libraries to OS provided callbacks.

One situation I find myself in quite often, is to call the OS to handle
some event, and have the the OS call me back, only for my code to
call another OS function ... that calls me back again from within
the first instance.

For this extremely frequent case of "re-entrency avoidance" the finally
construct is probaly the simplest/safest way to handle the case

void myCallBackFunc() {
static bool callBackReEntry = false ;
try {
if (callBackReEntry) return ;
callBackReEntry = true ;
allocResources()
callOSThatMayCallBackHereAgain() ;
} finally {
callBackReEntry = false ;
}
}
 
V

verec

That is certainly false. RAII is needed to ensure proper, automatic and
deterministic deallocation of your resources. finally is an errorprone
hack for languages that do not have RAII and it forces the user of the
class to be aware of whether RAII for every class is needed (and to
change his code if the class goes from a non-resource state to one
where it has resources), and it requires the programmer to write extra
code every time he uses a resource.

Here are feature A and feature B. I contend that B is good and A is crap.
You contend that A is good and B is crap. Fine. We can agree to disagree.

But what I cannot agree with, however, is your argument that because B hampers
A, so B must be crap. That's a stupid argument to throw at me since I
precisely beleive A is crap and couldn't care less if B hampers it or not.

In case you hadn't noticed: C++ is a big pile of shit. We haven't got anything
better, so we must put up with that crap, but it really feels like it
was designed
by Redmond :-(
 
B

benben

Well, in my world, I cannot even come close to the requirement that
I control 100% of the system. From libraries to OS provided callbacks.

One situation I find myself in quite often, is to call the OS to handle
some event, and have the the OS call me back, only for my code to
call another OS function ... that calls me back again from within
the first instance.

For this extremely frequent case of "re-entrency avoidance" the finally
construct is probaly the simplest/safest way to handle the case

void myCallBackFunc() {
static bool callBackReEntry = false ;
try {
if (callBackReEntry) return ;
callBackReEntry = true ;
allocResources()
callOSThatMayCallBackHereAgain() ;
} finally {
callBackReEntry = false ;
}
}

I can't agree what you described is "clean up" code.

Afterall, a simple lock class would simplify your code further:

void myCallBackFunc()
{
func_lock<void(void)> lock(myCallBackFunc);
if (!lock) return;

allocResources();
callOSThatMayCallBackHereAgain();
}


Regards,
Ben
 
B

benben

I think the finally block (__finally) was introduced in Microsoft's Managed
Extension of its own Visual C++ implementation years ago because they were
doing automatic garbage collection and RAII doesn't naturall go with it.
Now, with the redesigned C++/CLI (love and hate) they put RAII
(deterministic finalization they called) back into the language because they
found out without RAII (such as in C#), code tend to be notably messier and
harder to maintain. It's not just a matter of "clean up", its about resource
management strategy in general.

Regards,
Ben
 
V

verec

I can't agree what you described is "clean up" code.

Afterall, a simple lock class would simplify your code further:

void myCallBackFunc()
{
func_lock<void(void)> lock(myCallBackFunc);
if (!lock) return;

allocResources();
callOSThatMayCallBackHereAgain();
}

Well, I can concede the point ... :)

Except possibly for the fact that for every single pattern for
which finally was a unique solution, RAII mandates the definition
of an ad hoc class, as in your func_lock example: I know, I'm
translating Java code to C++, and find that I have to invent
a plethora of single point of use classes, just to replace a
finally ... :(

Speaking of which, the definition of your func_lock class may
prove an interesting exercise to the reader ...
 
R

Rene Moehring

Well, I can concede the point ... :)

Except possibly for the fact that for every single pattern for
which finally was a unique solution, RAII mandates the definition
of an ad hoc class, as in your func_lock example: I know, I'm
translating Java code to C++, and find that I have to invent
a plethora of single point of use classes, just to replace a
finally ... :(

The maybe the ScopeGuard of Andrei Alexandescu is worth a look for you.
 
M

msalters

benben schreef:
I think the finally block (__finally) was introduced in Microsoft's Managed
Extension of its own Visual C++ implementation years ago because they were
doing automatic garbage collection and RAII doesn't naturall go with it.
Now, with the redesigned C++/CLI (love and hate) they put RAII
(deterministic finalization they called) back into the language because they
found out without RAII (such as in C#), code tend to be notably messier and
harder to maintain.

True, and not only did they add RAII back to C++/CLI, they also added
RAII
to C# ( via the using( ) extension, IDispose IIRC ).

BTW, RAII works great with immediate garbage collection (i.e. all
pointers
behave like shared_ptr's, last one to go out of scope deletes the
object)

Regards,
Michiel Salters
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top