By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
439,993 Members | 1,984 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 439,993 IT Pros & Developers. It's quick & easy.

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

P: n/a
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.
Jul 23 '05 #1
Share this Question
Share on Google+
21 Replies


P: n/a
J. Smith wrote:

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?

--
Joe Seigh

When you get lemons, you make lemonade.
When you get hardware, you make software.
Jul 23 '05 #2

P: n/a
Joe Seigh wrote:
J. Smith wrote:
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?


It uses no static or global variables. But a new keyword is
'disproportionate'.

Jul 23 '05 #3

P: n/a
J. Smith wrote:
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'.

Jul 23 '05 #4

P: n/a
Ian
Joe Seigh wrote:
J. Smith wrote:

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?

Use of a non-local object maybe?

Ian
Jul 23 '05 #5

P: n/a
On 2005-07-17 00:08:31 +0100, "Mercator" <me********@spambob.com> said:
Joe Seigh wrote:
J. Smith wrote:
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?


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 :(
--
JFB

Jul 23 '05 #6

P: n/a
On 2005-07-17 00:10:43 +0100, "Mercator" <me********@spambob.com> said:
J. Smith wrote:
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'.


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.
--
JFB

Jul 23 '05 #7

P: n/a
> 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.
--
JFB


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
Jul 23 '05 #8

P: n/a
On 2005-07-17 01:56:00 +0100, "benben" <be******@hotmail.com> 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.


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.
--
JFB

Jul 23 '05 #9

P: n/a

"verec" <ve***@mac.com> wrote in message
news:42***********************@news.aaisp.net.uk.. .
On 2005-07-17 01:56:00 +0100, "benben" <be******@hotmail.com> 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.


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.
--
JFB


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
Jul 23 '05 #10

P: n/a
benben wrote:
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).

Jul 23 '05 #11

P: n/a
verec wrote:
On 2005-07-17 00:08:31 +0100, "Mercator" <me********@spambob.com> said:
Joe Seigh wrote:
So how would the compiler identify a non-reentrant function? It uses no static or global variables.


... 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 ;
}
But a new keyword is 'disproportionate'.


... 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/reen...tml#tag_foot_1

Jul 23 '05 #12

P: n/a

"verec" <ve***@mac.com> skrev i en meddelelse
news:42***********************@news.aaisp.net.uk.. .
On 2005-07-17 00:10:43 +0100, "Mercator" <me********@spambob.com> said:
J. Smith wrote:
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'.


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.
--
JFB

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
Jul 23 '05 #13

P: n/a
On 2005-07-17 07:38:05 +0100, "benben" <be******@hotmail.com> said:
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.


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 ;
}
}
--
JFB

Jul 23 '05 #14

P: n/a
On 2005-07-17 14:33:28 +0100, "Peter Koch Larsen" <pk*****@mailme.dk> said:
"verec" <ve***@mac.com> skrev i en meddelelse
news:42***********************@news.aaisp.net.uk.. .
On 2005-07-17 00:10:43 +0100, "Mercator" <me********@spambob.com> said:
J. Smith wrote:
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'.

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.


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 :-(
--
JFB

Jul 23 '05 #15

P: n/a
> 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 ;
}
}
--
JFB


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

Jul 23 '05 #16

P: n/a
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
Jul 23 '05 #17

P: n/a
On 2005-07-18 02:05:06 +0100, "benben" <be******@hotmail.com> said:
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();
}


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 ...
--
JFB

Jul 23 '05 #18

P: n/a
On Mon, 18 Jul 2005 23:24:34 +0100, verec wrote:
On 2005-07-18 02:05:06 +0100, "benben" <be******@hotmail.com> said:
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();
}


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.

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

--
I'm not a racist. I hate everyone equally!
Jul 23 '05 #19

P: n/a


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

Jul 23 '05 #20

P: n/a
On 2005-07-19 09:00:29 +0100, Rene Moehring <re***********@gmx.de> said:
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.


Cool!

I googled it down to:
http://www.cuj.com/documents/s=8000/...r/alexandr.htm

The irony, of course, is that I can now:

#define finally ON_BLOCK_EXIT :-)

Many thanks for the pointer.
--
JFB

Jul 23 '05 #21

P: n/a
J. Smith wrote:
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.


This is my current letter to Santa:

1) A new concept of resource location to replace #include. Rather than
#including simple text files into a concatanated monolithic text file called
a translation unit, it should be possible to import named resources. The
mapping from fully qualified identifier to the resource will be the
responsibility of the implementation. This is similar to the Java `import',
the Mathematica `Needs', or the ELisp `requires' directives.

If the resource is available in compiled form, then the public interface
declaration should be extracted from from the module, or otherwise made
available to the compiler with the expectation that the resource would be
available for linking. If the resource is not compiled, it should be
compiled automatically if needed by the linker.

2) A language construct that maps to a compiled entity with a clearly
defined,
self-describing interface. This would be similar to the Mathematica notion
of a package, and might be accomplished by leveraging the existing namespace
construct. The compiled module should be capable of communicating its
public
interface in terms of source-code declarations. Similar to the way the
Mathematica package system provides comments, or the Java javap mechanism
returns an interface description of a class.

The module identifier could serve as the name to be used for resource
location
in the previously described replacement for #include.

3) A formalization of the notion of a class _interface_ which we currently
express as a class definition in a "header file" and _implementation_ with
the member function implementations defined elsewhere (in a "source file").
Whether the class interface is contained in the same file as the
implementation is irrelevant. This division between interface and
implementation could be extended to encompass namespace local functions as
well as classes. This would further obviate the need for the #include
directive.

4) A local context text extrating mechanism which could be used to preserve
class, namespace, function, etc., textual information in the form of const
member variables, or function call parameter initializations. The purpose
of
this feature would be to provide the kind of functionality currently
provided
by Cpp token pasting and stringification, but in such a way as to respect
the
scoping and type rules of C++.

5) A built-in conditional compilation block structure which would be
controlled by setting constants at the appropriate scope before compiling.

6) A clear specification of the conceptual organization of resources such as
identifiers, declarations, definitions, etc., so that the same steps can be
carried out to locate any resource within the working code base. IOW, treat
the code base as a database with some kind of deterministic organization.
--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 23 '05 #22

This discussion thread is closed

Replies have been disabled for this discussion.