A good use of fn ptrs?

P

Protoman

Is this a good use of fn ptrs?

#include <iostream>
#include <cstdlib>
using namespace std;

typedef void (*v_v_fptr)();

void Error(){cout << "Error" << endl;}

void Success(){cout << "Success" << endl;}

v_v_fptr select(bool arg){if(arg==true)return Success; else return
Error;}

int main()
{
bool val;
cout << "1|0?: " << endl;
cin >> val;
v_v_fptr ptr=select(val);
ptr();
system("PAUSE");
return 0;
}

Or should I use fn objs instead? Thanks!!!
 
P

Protoman

How would I make it use fn objs? Like this:

class select
{
public:
v_v_fptr operator()(bool val){if(val==true)return Success;else return
Error;}
};
//...
v_v_fptr ptr=select()(val);
ptr();

Could you help? Thanks!!!
 
V

Viktor Prehnal

I am programming for more that 10 years in C++ but I have not seen such
a way of error checking. But syntatically it is correct. If I were you I
would use exceptions.
 
P

Protoman

Why use exceptions? This is just an examp; in a real prog, I'd use it
to determine what fn to call based on the val of a var.
 
V

Viktor Prehnal

Protoman said:
Why use exceptions? This is just an examp; in a real prog, I'd use it
to determine what fn to call based on the val of a var.
exceptions divide execution code from error checking code, that's the
reason why they were created....
 
G

Gianni Mariani

Viktor said:
exceptions divide execution code from error checking code, that's the
reason why they were created....

Is attempting to open a file that is not there an exception or an error?
 
B

Ben Pope

Gianni said:
Is attempting to open a file that is not there an exception or an error?

If the file was expected to exist, or if the file was necessary for the
program to operate, then almost certainly an exception.

If the filename was entered by the user, then probably an error,
although that error could easily be propagated up the stack by an
exception...

As is often the case, it depends!

Ben Pope
 
G

Gianni Mariani

Ben said:
Gianni Mariani wrote: ....


If the file was expected to exist, or if the file was necessary for the
program to operate, then almost certainly an exception.

If the filename was entered by the user, then probably an error,
although that error could easily be propagated up the stack by an
exception...

As is often the case, it depends!

So now, exceptions are glorified cross function gotos. Probably not a
good thing.

I was on the fence for quite a while on exceptions and I'm now leaning
on a very minimal usage of exceptions. Opening a file is in almost
every case I have come across, not a case for using exceptions, even if
you expect the file to exist.

It's also very unfortunate that exception specifiers are dynamically
handled rather than allowing the compiler to do a static analysis.

Multithreaded code is almost always impossible to manage using exceptions.

I'm not trying to say exceptions are bad, I'm saying they're very
limited in utility. Also, I find it a fallacy that code is easier to
write. Handling exceptions correctly can get quite involved making the
code much more difficult to write if you have to write try/catch blocks
everywhere.

Anyhow, I'm sure that there are plenty o people who would debate this,
and I'm looking forward to a constructive one.
 
K

Kai-Uwe Bux

Gianni said:
So now, exceptions are glorified cross function gotos. Probably not a
good thing.

Well, that is what throw and catch do: transfer control to the handler
unwinding the stack as much as necessary to get to the handlers context. I
can see two main differences to goto: (a) goto is a little less restricted
in where it can take you, but (b) the target of the jump is always known,
whereas a throw can take you to a place that you do not know in advance.

I was on the fence for quite a while on exceptions and I'm now leaning
on a very minimal usage of exceptions. Opening a file is in almost
every case I have come across, not a case for using exceptions, even if
you expect the file to exist.

I tend to advocate throwing whenever the construction of an object fails.
The reason is that I usually do not see a good way of dealing with
half-constructed objects. So, failure to claim a resource is, in my book,
always a good candidate for a throw().

It's also very unfortunate that exception specifiers are dynamically
handled rather than allowing the compiler to do a static analysis.

Multithreaded code is almost always impossible to manage using exceptions.

Could you elaborate on this one. I have no experience in multithreaded
programming, so I do not really understand what you are refering to.

I'm not trying to say exceptions are bad, I'm saying they're very
limited in utility. Also, I find it a fallacy that code is easier to
write. Handling exceptions correctly can get quite involved making the
code much more difficult to write if you have to write try/catch blocks
everywhere.

The unfortunate thing is that you have to beware of exceptions whether you
use them or not: code beyond your control may throw just as well. In the
context of another thread it recently dawned upon me that very innocent
looking code can actually leak resources when exceptions enter the picture:

template < typename T >
class X {

T* data;

public:

X ( T const & t )
: data ( new T )
{
*data = t; // this leaks the pointer if the assignment throws.
}

}; // X

Better:

template < typename T >
class X {

T* data;

public:

X ( T const & t )
: data ( new T( t ) )
{}

}; // X

The upshot is: you really have to go through your code thinking "this line
might throw, what happens" at every single line you encounter. I find that
very hard, indeed.


Best regards

Kai-Uwe Bux
 
J

Jim Langston

Protoman said:
Why use exceptions? This is just an examp; in a real prog, I'd use it
to determine what fn to call based on the val of a var.

Well, if you're alread evaluating a variable to determine which function to
call... why not just call the function there instead?

Instead of:
v_v_fptr ptr=select(val);
ptr();

Just have:
select(val);

and have your select function do:

void select(bool arg)
{
if(arg==true)
cout << "Success" << endl;
else
cout << "Error" << endl;
}

Or, if you want to keep your success and error functions call them instead.

void select(bool arg)
{
if(arg==true)
Success();
else
Failure();
}

I don't see that you are gaining anything by returning a function to call,
then just calling the function. You are just adding an (error prone) level
of complexity for no good reason.

Just because you *can* do something doesn't mean you *should*.
 
P

Protoman

Jim said:
Well, if you're alread evaluating a variable to determine which function to
call... why not just call the function there instead?

Instead of:
v_v_fptr ptr=select(val);
ptr();

Just have:
select(val);

and have your select function do:

void select(bool arg)
{
if(arg==true)
cout << "Success" << endl;
else
cout << "Error" << endl;
}

Or, if you want to keep your success and error functions call them instead.

void select(bool arg)
{
if(arg==true)
Success();
else
Failure();
}

I don't see that you are gaining anything by returning a function to call,
then just calling the function. You are just adding an (error prone) level
of complexity for no good reason.

Just because you *can* do something doesn't mean you *should*.

I was just doing it to learn about returning fn ptrs from fns; in a
real prog I would definitely not do this unless I had a *very good*
reason.
 
B

Ben Pope

Gianni said:
So now, exceptions are glorified cross function gotos. Probably not a
good thing.

Quite different to a goto.

When a failure occurs, it is often the case that you do not know how to
handle the error, and so you inform your caller. If you do it via error
codes, then the caller has to check the return value, and decide what to
do, possibly informing its caller via a return code.

This results in lots of checks of calls into function for errors that
rarely occur, and manually propagating the error up the call stack.

With exceptions, you can short-cut the call up the stack. This means
you deal with the error when you know how to do so.
I was on the fence for quite a while on exceptions and I'm now leaning
on a very minimal usage of exceptions. Opening a file is in almost
every case I have come across, not a case for using exceptions, even if
you expect the file to exist.

Often, yes. If for example the filename was provided on the command
line, to the program, and you do a bunch of stuff, then try to open the
file and it doesn't exist, rather than manually propagate the error up
the call stack with return codes you can just throw, and then catch it
near the top, and inform the user they can't spell.
It's also very unfortunate that exception specifiers are dynamically
handled rather than allowing the compiler to do a static analysis.

Yes, I would have preferred to have to explicitly specify anything that
a function could throw, and for the compiler to provide static analysis:

#include <iostream>

void fun1() {
throw "foo";
}
void fun2() throw() {
throw "bar";
}
void fun3() throw() {
fun1();
}

int main() {
try {
fun1();
} catch (char* e) {
std::cout << "This is expected to fail: " << e << std::endl;
}
try {
fun3();
} catch (char* e) {
std::cout << "This is NOT expected to fail: " << e << std::endl;
}

}

It's a shame that more analysis is not done to ensure that fun3 does not
throw. VC8 warns that fun2 throws, but does not warn that fun3 calls a
function that throws.
Multithreaded code is almost always impossible to manage using exceptions.

Surely you have to manage throwing, anyway?
I'm not trying to say exceptions are bad, I'm saying they're very
limited in utility. Also, I find it a fallacy that code is easier to
write. Handling exceptions correctly can get quite involved making the
code much more difficult to write if you have to write try/catch blocks
everywhere.

Exceptions are for exceptional situations, things which are really bad,
things you don't really know how to deal with. If you write code to
deal with it, it means you expect it to happen, in which case it may not
be best to consider it an exceptional situation.

The normal process of handling errors via return codes is often the most
practical way of dealing with an error, especially if the caller of the
function experiencing the error can deal directly with it.

If it really is exceptional, it's likely that you can't deal with it
directly at the call site, you may have to get 10 calls up the stack to
deal with it, so it's often more manageable to throw.
Anyhow, I'm sure that there are plenty o people who would debate this,
and I'm looking forward to a constructive one.

It could be interesting!

Ben Pope.
 
D

deane_gavin

Ben said:
Exceptions are for exceptional situations, things which are really bad,
things you don't really know how to deal with. If you write code to
deal with it, it means you expect it to happen, in which case it may not
be best to consider it an exceptional situation.

The normal process of handling errors via return codes is often the most
practical way of dealing with an error, especially if the caller of the
function experiencing the error can deal directly with it.

If it really is exceptional, it's likely that you can't deal with it
directly at the call site, you may have to get 10 calls up the stack to
deal with it, so it's often more manageable to throw.

You could also find fully expected error situations arising several
levels down the call stack from where they need to be handled simply
because you have sensibly factored your code in many small functions
rather than few larger ones.

In such cases, even though the 'error' might be expected I find
exceptions a much cleaner control structure than having to propogate an
error code up the call stack manually. Debating the definitions of
'error situation' and 'exceptional situation' seems academic to me when
what I am really choosing between is clean code vs cluttered code.

Gavin Deane
 
G

Geo

Gianni said:
So now, exceptions are glorified cross function gotos. Probably not a
good thing.

while, for if..else.. return, break, continue... are ALL glorified
gotos, you advising against those also ?
I was on the fence for quite a while on exceptions and I'm now leaning
on a very minimal usage of exceptions. Opening a file is in almost
every case I have come across, not a case for using exceptions, even if
you expect the file to exist.

It's also very unfortunate that exception specifiers are dynamically
handled rather than allowing the compiler to do a static analysis.

Possibley, as they stand they are useless, but I'm not conviced they
have any worth anyway.
Multithreaded code is almost always impossible to manage using exceptions.

What's that got to do with anything, C++ is NOT a multithreaded
language, threading is not part of C++, exceptions are, you would be
more correct to say, use exceptions, don't use threads
I'm not trying to say exceptions are bad, I'm saying they're very
limited in utility. Also, I find it a fallacy that code is easier to
write. Handling exceptions correctly can get quite involved making the
code much more difficult to write if you have to write try/catch blocks
everywhere.

But you don't, that's the point, you only need to catch at the place
you wish to deal with the excaption, return codes on the other hand, do
need to be dealt with everywhere
Anyhow, I'm sure that there are plenty o people who would debate this,
and I'm looking forward to a constructive one.

Enjoy... :)
 

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,780
Messages
2,569,611
Members
45,280
Latest member
BGBBrock56

Latest Threads

Top