Behavior of numeric::to_int() and numeric::to_long()

These methods, and the corresponding functions taking the argument as a const numeric& parameter, when something goes wrong print a line of the form
Not a 32-bit integer: -9223372028264841216
on cerr and exit the program. Wouldn't throwing a suitable standard exception (like std::domain_error) be a better option? All the best
Roberto

Roberto Bagnara wrote:
These methods, and the corresponding functions taking the argument as a const numeric& parameter, when something goes wrong print a line of the form
Not a 32-bit integer: -9223372028264841216
on cerr and exit the program. Wouldn't throwing a suitable standard exception (like std::domain_error) be a better option?
And, by the way, the message above is hardcoded into CLN. Does this mean that CLN (and thus GiNaC) does not support 64 bits architectures? All the best
Roberto

On Tue, 1 Oct 2002, Roberto Bagnara wrote: [...]
And, by the way, the message above is hardcoded into CLN. Does this mean that CLN (and thus GiNaC) does not support 64 bits architectures?
Sure it does support 64 bit architectures. I have personally used it on Alpha and IA-64.
Note that type int is just 32 Bits on those architectures, anyways. If you are interested in more details, please consult the header file cln/object.h where the line between fixnums and bignums is drawn.
Regards -richy.

Richard B. Kreckel wrote:
On Tue, 1 Oct 2002, Roberto Bagnara wrote: [...]
And, by the way, the message above is hardcoded into CLN. Does this mean that CLN (and thus GiNaC) does not support 64 bits architectures?
Sure it does support 64 bit architectures. I have personally used it on Alpha and IA-64.
Note that type int is just 32 Bits on those architectures, anyways. If you are interested in more details, please consult the header file cln/object.h where the line between fixnums and bignums is drawn.
You are right, of course. I had misinterpreted the CLN sources. Thanks
Roberto

On Tue, 1 Oct 2002, Roberto Bagnara wrote:
These methods, and the corresponding functions taking the argument as a const numeric& parameter, when something goes wrong print a line of the form
Not a 32-bit integer: -9223372028264841216
on cerr and exit the program. Wouldn't throwing a suitable standard exception (like std::domain_error) be a better option?
Not really. We want them to be fast. They are intended for use in main loops only and if you look into the code you'll see that we don't even check whether they are actual integers. The programmer should care about that...
Regards -richy.

Richard B. Kreckel wrote:
On Tue, 1 Oct 2002, Roberto Bagnara wrote:
These methods, and the corresponding functions taking the argument as a const numeric& parameter, when something goes wrong print a line of the form
Not a 32-bit integer: -9223372028264841216
on cerr and exit the program. Wouldn't throwing a suitable standard exception (like std::domain_error) be a better option?
Not really. We want them to be fast. They are intended for use in main loops only and if you look into the code you'll see that we don't even check whether they are actual integers. The programmer should care about that...
I agree on what you say. This is even stated in the documentation.
What I am saying is that, instead of writing "Not a 32-bit integer..." and exiting, you could throw an exception. This would not impede performance, since the test now controlling the printing would then control the throw. The change I am proposing would make debugging much easier and would make possible recovering from the error (and this is the thing that is very important to us). All the best
Roberto

On Tue, 1 Oct 2002, Roberto Bagnara wrote:
What I am saying is that, instead of writing "Not a 32-bit integer..." and exiting, you could throw an exception. This would not impede performance, since the test now controlling the printing would then control the throw.
Unfortunately this is not true since it would prohibit compilation of CLN with the option -fno-exceptions. CLN is designed in such a way that ranges must be checked before the calls are made for reasons of efficiency. Apart from having a register less maybe, the problematic part is the dtors' overhead needed for stack unwinding.
The change I am proposing would make debugging
much easier and would make possible recovering from the error (and this is the thing that is very important to us).
You'll have to check yourself at those places where an over/underflow may happen for numeric::to_int() and numeric::to_long(), I'm afraid. The other such checks you were proposing will be applied to CVS in some minutes, though.
Regards -richy.

Richard B. Kreckel wrote:
On Tue, 1 Oct 2002, Roberto Bagnara wrote:
What I am saying is that, instead of writing "Not a 32-bit integer..." and exiting, you could throw an exception. This would not impede performance, since the test now controlling the printing would then control the throw.
Unfortunately this is not true since it would prohibit compilation of CLN with the option -fno-exceptions. CLN is designed in such a way that ranges must be checked before the calls are made for reasons of efficiency. Apart from having a register less maybe, the problematic part is the dtors' overhead needed for stack unwinding.
The change I am proposing would make debugging
much easier and would make possible recovering from the error (and this is the thing that is very important to us).
You'll have to check yourself at those places where an over/underflow may happen for numeric::to_int() and numeric::to_long(), I'm afraid. The other such checks you were proposing will be applied to CVS in some minutes, though.
OK. Let me see if I understand correctly: this design goal of CLN concerning compilation with -fno-exceptions also affects
numeric::numeric(const char *)
and
const numeric & operator=(const char *s).
If something goes wrong they just print "Illegal number syntax" and exit so that, if we want robustness, we ought to do our own syntax checking before calling them. Is this right?
And, since you are also the CLN maintainer, wouldn't be possible/easy to provide a --enable-exceptions configuration option to CLN? At a first sight it seems that the modular design of CLN would make this task not very difficult. In a first version, when --enable-exceptions, fprint() should not print and cl_abort() should throw an exception instead of exiting. This would constitute a rough approximation but a definite improvement over the current state. Later, one could modify, e.g., read_number_bad_syntax() so as to throw, say, std::invalid_argument("Illegal number syntax: ..."). Just an idea. All the best
Roberto

On Tue, 1 Oct 2002, Roberto Bagnara wrote:
OK. Let me see if I understand correctly: this design goal of CLN concerning compilation with -fno-exceptions also affects
numeric::numeric(const char *)
and
const numeric & operator=(const char *s).
If something goes wrong they just print "Illegal number syntax" and exit so that, if we want robustness, we ought to do our own syntax checking before calling them. Is this right?
No, -fno-excpetions does not affect class numeric. Actually, the cleanest way would be if the routines you mention would do the checking and throw if they encounter garbage. I see that they don't do that completely and I would consider this a bug. You can trigger things, if you try hard enough. Patches for numeric::numeric(const char *) are very welcome but doing the checks outside is ugly IMO and shouldn't be needed.
But why is this a problem? Are you writing a frontend parser that must be totally foolproof or what?
And, since you are also the CLN maintainer, wouldn't be possible/easy to provide a --enable-exceptions configuration option to CLN?
Possibly it would be possible and easy but at the cost of speed. See below...
At a first sight it seems that the modular design of CLN would make this task not very difficult.
The modular design is of little help here, since the ctors and dtors are all over the place and enabling exceptions at one place is certainly not possible. It would have the full impact.
In a first version, when --enable-exceptions,
fprint() should not print and cl_abort() should throw an exception instead of exiting. This would constitute a rough approximation but a definite improvement over the current state. Later, one could modify, e.g., read_number_bad_syntax() so as to throw, say, std::invalid_argument("Illegal number syntax: ...").
That would have to be compiled in, maybe using preprocessor switches, of course! I have no plans or resources for doing so, currently, tough I consider the idea worth following.
It would really be good to carefully measure the impact of enabled exceptions with recent versions of GCC by running some benchmarks. I understand that there was some progress with respect to GCC-2.x though I don't know how much.
Why not ask an expert?!
Gaby, can you point us to any benchmarks or guesstimates that would be helpful for getting a picture of the real difference?
Regards -richy.
participants (2)
-
Richard B. Kreckel
-
Roberto Bagnara