[GiNaC-list] Include Guards
Jason Dusek
jason.dusek at gmail.com
Fri Jan 21 02:41:03 CET 2005
What if I define the symbol as a static variable in a class header?
// <Evil.h>
#include <one_of_everything>
class Evil
{
public:
static symbol x("x");
void showMeTheEvil()
{
cout << x;
};
// </Evil.h>
// <even_more_evil.cpp>
#include <Evil.h>
int
main(int argc, char* argv)
{
Evil evil;
evil.showMeTheEvil();
}
// </even_more_evil.cpp>
I am fine with OO evil - making a global symbol server class, for
example - but I can brook no other evil!
_jason
On Thu, 20 Jan 2005 11:47:04 +0300, Sheplyakov Alexei
<varg at theor.jinr.ru> wrote:
> On Wed, Jan 19, 2005 at 03:55:19PM -0600, Jason Dusek wrote:
> > In the FAQ, they discuss a problem with multiple inclusions of a
> > header where global symbols are defined:
>
> The problem has NOTHING to do with multiple inclusions of a
> header. The actual problem is declaration of global variables
> in different compilation units by inclusion a _single_ header
> file, like this:
>
> // file bogus.h
> #ifndef VARGS_BOGUS_H
> #define VARGS_BOGUS_H
> #include <ginac/ginac.h>
> const GiNaC::symbol x("x");
> #endif
>
> // file fun1.cpp
> #include <ginac/ginac.h>
> #include "bogus.h"
> const GiNaC::ex fun1() { return x; }
>
> // file fun2.cpp
> #include <ginac/ginac.h>
> #include "bogus.h"
> const GiNaC::ex fun2() { return x; }
>
> // file main.cpp
> #include <iostream>
> #include <ginac/ginac.h>
> using namespace std;
> using namespace GiNaC;
> extern const ex fun1();
> extern const ex fun2();
>
> int main(int argc, char* argv)
> {
> ex bogus = fun1() - fun2();
> // print expression as a tree
> cout << tree << bogus << endl;
> return 0;
> }
>
> On my system, this program will print
>
> add @0x805ef88, hash=0xb7e7ae1a, flags=0x3, nops=2
> x (symbol) @0x805eda8, serial=2, hash=0x670d3697, flags=0xf, domain=0
> 1 (numeric) @0x804fde8, hash=0x160af41d, flags=0xf
> -----
> x (symbol) @0x805ed70, serial=1, hash=0x79ba0000, flags=0xf, domain=0
> -1 (numeric) @0x804fc58, hash=0xd60af41d, flags=0xf
> =====
>
> So, `bogus' is _not_ zero, because there are two _different_ symbols
> (with the same print-name x): one of them was defined in the file
> fun1.cpp, another -- in fun2.cpp. Note, that in this example header
> file "bogus.h" gets included only once.
>
> > ================================================
> > Q: I have various modules, some global variables and...
> >
> > A: ...and you are getting weird results with symbols not being
> > identical? Imagine this situation: A file globals.h declares symbol
> > x("x"). Two other modules #include "globals.h", do something with
> > symbol x and return an expression ex containing the symbol to the
> > caller (e.g. to main()). When the caller combines the two expressions
> > there are really two different symbols both with the same print-name
> > x. This may cause terms like x-x to stay around which will never be
> > simplified to 0 because the system has no knowledge that the two
> > symbols are supposed to be the same. How should it? After all the
> > declarations really happend in different compilation units!
> > ================================================
> > Can include guards solve this problem?
>
> No, they can't.
>
> > Do I *have* to make that evil factory initializer thingy?
>
> You might use something like
>
> // file bogus.h
> #ifndef VARGS_GLOBAL_X_H
> #define VARGS_GLOBAL_X_H
> #include <ginac/ginac.h>
> extern GiNaC::symbol x;
> #endif
>
> // file bogus.cpp
> #include <ginac/ginac.h>
> #include "bogus.h"
> using namespace GiNaC;
> symbol x("x");
>
> // file fun1.cpp
> #include <ginac/ginac.h>
> #include "bogus.h"
>
> const GiNaC::ex fun1() { return x; }
>
> // file fun2.cpp
> #include <ginac/ginac.h>
> #include "bogus.h"
>
> const GiNaC::ex fun2() { return x; }
>
> // file main.cpp
> #include <iostream>
> #include <ginac/ginac.h>
> using namespace std;
> using namespace GiNaC;
> extern const ex fun1();
> extern const ex fun2();
>
> int main(int argc, char* argv)
> {
> ex bogus = fun1() - fun2();
> // print expression as a tree
> cout << tree << bogus << endl;
> // will print zero
> return 0;
> }
>
> But (IMHO) such a code is even more evil :)
>
> Best regards,
> Alexei.
>
> _______________________________________________
> GiNaC-list mailing list
> GiNaC-list at ginac.de
> http://thep.physik.uni-mainz.de/mailman/listinfo/ginac-list
>
--
_jason
More information about the GiNaC-list
mailing list