[c++] problem a function

Z

ZikO

Hi

I recently made a little program which generates ASCII file for another
program. One of the functions there generates number and returns that as
double:

double getNumber(...) {
// code
return double(...);
}

If in the function something goes wrong I return 0.0. Although it's
working for my little program very well I found that I might need 0 as a
proper returned value. What am I supposed to do to "inform"/indicate
that something is wrong in function if it can return everything even 0?

Thanks.
 
Z

ZikO

Exceptions are great. Once you throw, you never return.

so far Victor gave me quite good slution: numeric_limits<double>::infinity()

It works because infinity is different that max value in double. Well,
exceptions seems to be more formal as you are saying but I do not feel
them yet. I do not know which exception I would have to throw. I know
how to write the code:

double getNumber(...) {
// code
if(everything's good) return value;
if (something wrong) {
throw(exception);
}
}

int main() {
double v;
try {
val = getNumber(...);
} catch(...) {
// handling the exception
}
}

To be honest Im not sure what should be in brackets of throw() and
brackets of catch(). lol, this is what I need to work on yet.

Regards.
 
D

Daniel Pitts

ZikO said:
Hi

I recently made a little program which generates ASCII file for another
program. One of the functions there generates number and returns that as
double:

double getNumber(...) {
// code
return double(...);
}

If in the function something goes wrong I return 0.0. Although it's
working for my little program very well I found that I might need 0 as a
proper returned value. What am I supposed to do to "inform"/indicate
that something is wrong in function if it can return everything even 0?

Thanks.

Two possible answers:

bool getNumber(double &target) {
if (fail) return false;
target = double(result);
return true;
}

double getNumber() {
if (fail) throw some_exception;
return double(result);
}

There are probably many other possible solutions, but those are the two
that come to mind immediately.
 
Z

ZikO

Daniel said:
bool getNumber(double &target) {
if (fail) return false;
target = double(result);
return true;
}
Oh yes I forgot I could send a reference of a variable I would like to
change. Thanks
 
J

James Kanze

ZikO wrote:
What you've just said is, "I need a separate return path for
error-reporting, and I'm trying to fake one by returning an
out-of-band value through the regular return path."

No he didn't. What he said is that he needs a unique value to
indicate an error condition. Or rather, that the function
returns two pieces of information: whether it has succeeded or
not, and if it succeeds, the value.
You don't have to fake it, though, because C++ provides a
separate return path especially for errors: The exception
mechanism.

If the errors are "exceptional", and should be handled far from
the calling site, this is the appropriate solution. If the
error is something more or less expected from time to time, and
must be handled immediately in the calling function, returning a
Fallible is probably a better solution.
Libraries that don't offer exceptions, e.g. POSIX, typically
require the client to check the return value, then possibly a
quasi-global error code, after every library call. An
alternative is to cram two values into one; this is how we get
nonsense like getchar returning int.

I wouldn't take Posix as an example of good design. There's a
lot of historical garbage in there.

The fact that getchar returns int, however, isn't part of it.
First, of course, its not Posix, per se, but C---it's part of
Posix because Posix incorporates the C standard. More to the
point, however, if you'll look at any parsing algorithms, you'll
find that they work best if end of input is just another
character. In this case, defining the function to return 257
possible values (rather than the 256 characters) is a very good
idea---especially since all of the functions in <ctype.h> accept
all 257 values. (Allowing plain char to be signed, of course,
was a very bad idea, since it means that the results of
converting the return value of getchar() into a char, even after
checking for EOF, are implementation defined. And may result in
an implementation defined signal being raised.)
Exceptions are great. Once you throw, you never return.

Which isn't always what is wanted. Exceptions are great for
what they were designed to do, but one size doesn't fit all.
Without knowing more about what type of errors he's talking
about and how they should be handled, we can't say whether
exceptions are the best solution or not.
 
J

James Kanze

ZikO wrote:
Two possible answers:
bool getNumber(double &target) {
if (fail) return false;
target = double(result);
return true;
}
double getNumber() {
if (fail) throw some_exception;
return double(result);
}
There are probably many other possible solutions, but those
are the two that come to mind immediately.

You've missed the most frequent:

Fallible< double >
getNumber()
{
Fallible< double > result ;
if ( ! fail ) {
result.validate( ... ) ;
}
return result ;
}

(I can't imagine anyone writing C++ and not having Fallible in
their toolkit.)
 
Z

ZikO

(I can't imagine anyone writing C++ and not having Fallible in
their toolkit.)

Dear James

I am not professional programmer though I am thinking of it. I am still
learning C++ and a lot of things are new for me. I do not really know
whether to blame the book I have read and its author or me I have not
noticed there would be something like that.

One thing is sure, thanks to this group I can learn much more than from
books.

Thanks.
 
J

James Kanze

Certainly, plenty of useful tools are underutilized. The fact
that somebody isn't using a particular tool, though, does not
mean that they are doing something wrong. James has a habit
of claiming that failure to use his own favorite features is
"stupid."

It rubs me the wrong way.

I think you misunderstand my propos. It's not a question of
"favorite" tools. There is a wide assortment of tools
available: refusing to use a particular tool, or a particular
subset of the them, for some more or less ideological reason is
stupid.

In the case of Fallible, we are talking about an established
technique, which I would expect any experienced C++ (or most
other languages) programmer to be familiar with. And I find it
rather frustrating that this often isn't the case; it's
certainly a useful tool to have available. (Which doesn't mean
you should use it everywhere---there are cases where other
solutions are more appropriate.)
 
K

Kai-Uwe Bux

James said:
I think you misunderstand my propos. It's not a question of
"favorite" tools. There is a wide assortment of tools
available: refusing to use a particular tool, or a particular
subset of the them, for some more or less ideological reason is
stupid.

Here the additional hypothesis that the tool is nor used for "some more or
less ideological reason" sneaks in. Even if local coding standards should
explicitly forbid the use of the certain tool, I would not assume some
ideology to be the driving cause behind. Each and every tool is used
throughout a shop requires the programmers who work there to familiarize
themselves with the tool. The more tools, the steeper the learning curve.

Most of the time, however, I would not expect coding standards to prevent
the use of a particular technique. If the technique isn't used, it's most
likely because the developers didn't think of it.

In the case of Fallible, we are talking about an established
technique, which I would expect any experienced C++ (or most
other languages) programmer to be familiar with. And I find it
rather frustrating that this often isn't the case;

That observation should give you reason to revisit your assumption. _Why_ do
you expect any experienced C++ programmer to be familiar with Fallible?
Given that C++ is a multiparadigm language used for a vast variety of
purposes, I think there are plenty of ways to accumulate experience without
coming across Fallible. (More precisely, I think, that for any particular
technique X, you can gather much experience yet never run into X. So no
single technique can serve as a litmus test for experience.)
it's certainly a useful tool to have available.

On that, I wholeheartly agree. I have to admit that it was the first to come
to my mind with regard to the OP's problem, too.
(Which doesn't mean
you should use it everywhere---there are cases where other
solutions are more appropriate.)

True.


Best

Kai-Uwe Bux
 
Z

ZikO

Jeff said:
double divide(double dividend, double divisor) {
if (divisor == 0.0) {
throw "you tried to divide by zero, you boob";
}
return dividend / divisor;
}

#include <cstdlib>
#include <iostream>

int main() try {
divide(42.0, 0.0);
return EXIT_SUCCESS;
} catch (char const* s) {
std::cerr << "error: " << s << '\n';
return EXIT_FAILURE;
}

It's much simpler that I expected :p

Thanks
 
J

James Kanze

Here the additional hypothesis that the tool is nor used for
"some more or less ideological reason" sneaks in.

Sort of. The link Jeff posted referred to a discussion of
garbage collection. My use of "stupid" in that discussion was
in a very specific context, where the argument was against
introducing garbage collection into the language (i.e. against
supporting the tool, rather than against using it in a specific
context), and were purely ideological (garbage collection
renders otherwise competent programmers idiots, and such).

Having a tool available, and banning it per se, is stupid.
Trying to limit its availability to other programmers is even
worse. Like all tools, however, it isn't a silver bullet, and
shouldn't be used everywhere, and it doesn't solve all problems.
Even if local coding standards should explicitly forbid the
use of the certain tool, I would not assume some ideology to
be the driving cause behind. Each and every tool is used
throughout a shop requires the programmers who work there to
familiarize themselves with the tool. The more tools, the
steeper the learning curve.

That's what I'd call a "political" motivation. Except that the
word political is loaded with negative connotations which don't
apply here. But I don't know of another word which means the
same thing in its original sense. (In fact, I'm thinking of the
French word "politique", which originally meant anything related
to organized société, and can even today be used positively.)
Most of the time, however, I would not expect coding standards
to prevent the use of a particular technique. If the technique
isn't used, it's most likely because the developers didn't
think of it.

If the technique requires significant external support (e.g.
like garbage collection, or a GUI library), I would expect the
decision to be made on a project basis, and consecrated in the
coding guidelines of the project. If you want to use garbage
collection, then the time necessary to integrate the Boehm
collector will have to be planned into the project, and if the
project is using Qt, then you can't use wxWidgets for your
particular components.

In cases like Fallible, of course, I can't imagine a coding
guideline forbidding it, and an individual who thinks of it can
easily introduce it. On the other hand, there's something to be
said for standardizing the mechanisms of error reporting (for
the specific cases, e.g. if the error should be handled
immediately), and it's probably worthwhile for a project to have
a single instance of Fallible, somewhere in its basic library.
That observation should give you reason to revisit your
assumption. _Why_ do you expect any experienced C++ programmer
to be familiar with Fallible?

Wishful thinking? :) Maybe because it's been around for so
long.
Given that C++ is a multiparadigm language used for a vast
variety of purposes, I think there are plenty of ways to
accumulate experience without coming across Fallible. (More
precisely, I think, that for any particular technique X, you
can gather much experience yet never run into X. So no single
technique can serve as a litmus test for experience.)

You're probably right, of course. But it's still frustrating
that so many programmers apparently aren't aware of such a basic
technique.
 
J

James Kanze

[...]
Well, I understand frustration, anyway. Since I respect your
opinion, it irks me that you "can't imagine" how someone gets
along fine without Fallible, GC, or whatever other tools you
personally have found useful.

It's not that I can't imagine how someone gets along without it;
I got along without it before I knew it as well. What I do find
frustrating (and what I can't imagine) is that someone today
would be unaware of the technique.

And note that this is completely different than the issue
concerning garbage collection, where a number of people are
opposed to making the tool available (i.e. by not adopting it
into the language) for purely ideological reasons.

There are clearly cases where Fallible or garbage collection is
not the right (or at least not the best) answer. There are just
as clearly cases where they are, however, and I have very little
tolerance for people who refuse to use it in such cases
(although I don't know any concerning Fallible), and even less
for those who would try to limit others' use of it (and to be
really effective as a tool, garbage collection must be part of
the language).
 
J

James Kanze

I'm not sure they're ever the best tools to choose in a green
field C++ project, but people have obviously found them both
useful.

There the most appropriate tools when they're the most
appropriate tools. In the case of Fallible, green field is
irrelevant, and in the case of garbage collection, it's almost
impossible to retro-fit into an existing implementation, so
green field projects are the only ones which can effectively use
it.
I'm against imposing the overhead of supporting GC, in terms
of development, integration, testing, and documentation, on
all compliant implementations. IMO, it's just not a very
useful feature.

And that's really an ideological statement, not backed up by
hard facts. It's almost essential for certain types of
applications (not mine, but I do know of some). And it reduces
the amount of work necessary to implement most applications
(albeit not always by an enormous amount).

And the overhead for a compiler implementor isn't that great;
certainly a lot less than e.g. concepts.
I don't dispute for one moment your right to use it, but I see
this as a QoI issue, not something that should be required by
the standard. This isn't ideological for me at all, btw; if I
saw a real gain to be had by using language-level GC in C++,
the first thing I'd do is try to figure out which compiler had
the best support for it, and the second thing I'd do is try
that compiler.

The problem is that it affects the language---it's not just a
library that you can add in. Current implementations make a
number of assumptions about how compilers work, and how people
write code. At the very least, those assumptions must be
integrated into the language definition.
 

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,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top