Euphoria
Ticket #974:
Use either matherr or math_error
-
Reported by
SDPringle
Jul 15, 2018
Source should compile using the math_error interface when matherr is not available. When both available, allow a choice with configure script.
This ticket was created as a result of the following post https://openeuphoria.org/forum/132849.wc
Details
1. Comment by SDPringle
Jul 19, 2018
Should we simply conditionally compile matherr() only when the matherr macro exists?
I took a look at the matherr function implementation. It seems the idea of matherr() is you write a function with the name matherr and it becomes your handler for floating point exceptions without the need of setting it up the handler function.
I went to the tests directory of the head (mercurial checkout) of the default branch and issued
egrep 'math function .* error' ../source/*.c *.d/control.err
The response was a surprise to me:
../source/be_runtime.c: RTFatal("math function %s error", msg);
That line is from the matherr() function itself. Therefore, there are no unit tests that provoke errors that display this error message. If I simply delete this from the source, I wont expect any unit tests to fail. I think because Euphoria has a lot of checking, this would happen if you are using the C-interface to interact with the C-implementation of math functions.
So, there needs to be more unit-tests for math in order for this to show its worth. If I write a custom log function in C, and call it with an illegal value, I think this will be triggered.
For most uses matherr is a redundant safety-net. For us devs, if sometime in the future there is a bug in checking code somewhere else, the counter-test will fail with the wrong error message and at least we can better diagnose what we did wrong.
I think that the matherr interface is still a good thing to have for older libraries that still support it.
2. Comment by SDPringle
Jul 19, 2018
I wrote this tiny program in order to provoke matherr to run. I did not succeed.
include std/machine.e
include std/dll.e
include std/utils.e
include std/io.e
-- Euphoria assert
type truth_type(object x)
return not equal(x,0)
end type
truth_type truth
-- Returns zero on my machine. Weird eh?
constant libc = open_dll("libc.so")
-- Used to return function offsets from the EUI binary
constant this_binary = 0
-- -1 on failure
constant logp = define_c_func(libc, "log", {C_DOUBLE}, C_DOUBLE)
-- -1 on error
constant matherr = define_c_func(this_binary, "matherr", {C_POINTER}, C_INT)
-- -1 on failure
constant error_no_p = define_c_var(libc, "errno")
truth = logp >= 0 and error_no_p >= 0
poke4(error_no_p, 0)
procedure printoutlogfln(integer i)
printf(io:STDOUT, "log(%d) = %f, ", {i, c_func(logp, {i})})
printf(io:STDOUT, "error number = %d.\n", {peek4u(error_no_p)})
end procedure
printf(io:STDOUT, "There is %s matherr defined in this Euphoria binary\n", {iif(matherr != -1, "a", "no")})
printoutlogfln(100)
printoutlogfln(10)
printoutlogfln(1)
printoutlogfln(0)
printoutlogfln(-1)
The output is
There is a matherr defined in this Euphoria binary
log(100) = 4.605170, error number = 0.
log(10) = 2.302585, error number = 0.
log(1) = 0.000000, error number = 0.
log(0) = -inf, error number = 34.
log(-1) = nan, error number = 33.
When calling the C function log via the C interface the matherr utility should have been triggered. On mine rather than failing at compile time, it compiles fine but doesn't exit and create an ex.err file. Perhaps others will have distinct results.
3. Comment by SDPringle
Jul 19, 2018
A change has been committed to fix this bug in the 4.0 branch. It's hash is 428ad2be620fd3e6ca95d0ddb66bf9c09f61f226.
4. Comment by SDPringle
Jul 19, 2018
Since Euphoria builtins as a matter of policy checks its parameters for validity, the matherr routine would only get called if in the future there is parameter check missing bug in the interpreter itself.
It turns out due to the flags used to compile the interpreter, the other math_error interface is not available for us. So, this is simply left out.