Hi, The patch written by Chris can fix the problem that I posted on 28 Dec 2004, right? Because I found that the cause for that error is not only setting the compiler option -fexceptions... Best wishes, -Qin An
On Thu, 6 Jan 2005, Chris Dams wrote:
Chris, I'm afraid you introduced a new static initialization order problem when you sent us your integral.cpp file. You cannot initialize static ex integral::relative_integration_error like you do in integral.cpp:206.
Hmmm... Wait a minute... If I understand correctly, this means that initialization of integral::relative_integration_error occurs before the initialization of the library_init of the same file integral.o as well as before the initialization of all other library_init objects in all GiNaCs other object files. Isn't this a bit strange???
Now that you mention it...
I mean, can't the runtime environment (or whatever it is called) just initialize static objects in the same order as they are defined in the preprocessed C++-code???
Sure. The language guarantees exactly that.
If the order of static initialization were the same as the order of definition were the same, there would not be a problem, right?
Right.
But wait a minute! The problem comes from ex::is_zero() const in ex.h:208: There we have the inline member function
bool is_zero() const { extern const ex _ex0; return is_equal(_ex0); }
But have a look at utils.cpp. Initialization jumps from all the modules that include ex.h into the ctor of library_init and there all the numeric objects are initialized. But _ex0 is declared above that ctor and it is not initialized until the module utils.o is initialized itself! Just the jumps into that ctor do not as a by-product initialize all the static objects.
If that analysis is correct there appears to be a loophole in the initialization order scheme. I wonder how that can be fixed without creating a big mess in utils.cpp...
Would you please be so kind and sent a patch to this list for my review?
I would suggest the change in the attached patch, since the functions that are used in this patch do not seem to involve any static variables. Unfortunately I do not know how to test this, because at my place no crash occured in the first place. Do you think this is sufficient to avoid a crash in all cases?
Your patch seems to work, thanks a lot! The patch below seems to fix the problem just as well. By virtue of ex::construct_from_double(double) it should be equivalent to your patch. If you have no objections, I'll commit it.
diff -a -u -r1.2 integral.cpp --- integral.cpp 14 Oct 2004 15:36:45 -0000 1.2 +++ integral.cpp 6 Jan 2005 21:31:23 -0000 @@ -203,7 +203,7 @@ }
int integral::max_integration_level = 15; -ex integral::relative_integration_error = power(10,-8).evalf(); +ex integral::relative_integration_error = 1e-8;
ex subsvalue(const ex & var, const ex & value, const ex & fun) {
Best wishes -richy. --