[msvc] Work around strange scoping and name mangling rules.
authorJan Rheinländer <jrheinlaender@gmx.de>
Mon, 20 Sep 2010 12:23:14 +0000 (12:23 +0000)
committerAlexei Sheplyakov <Alexei.Sheplyakov@gmail.com>
Fri, 26 Nov 2010 22:15:55 +0000 (00:15 +0200)
1. msvc creates different symbols for a variable declared in
   a namespace scope and (the same variable) in a class method
   scope. That is,

   // util.cpp
   namespace GiNaC {
   extern const ex _ex0; // [1]
   }
   // ex.h
   namespace GiNaC {
   class ex {
   public:
          bool is_zero() {
                extern const ex _ex0;
                // mangled name of _ex0 is different that of [1]
          }
   };
   }

2. The mangled names for cv-qualified and cv-unqualified versions
   of a type are different (which violates the requirements stated
   in [basic.type.qualifier])

These msvc's "features" cause linking failures due to unresolved
external symbols.

Solution:
1. Declare variables (_ex0) in the GiNaC namespace scope (for msvc only).
2. Add corresponding cv-qualifier(s).

ginac/ex.h
ginac/parser/parse_binop_rhs.cpp
ginac/parser/parser.cpp

index f0e6db5..d7bbf6d 100644 (file)
 #include <stack>
 
 namespace GiNaC {
+#ifdef _MSC_VER
+  // MSVC produces a different symbol for _ex0 when it is declared inside   
+  // ex::is_zero() than when it is declared at top level as follows
+  extern const ex _ex0;
+#endif
 
 /** Helper class to initialize the library.  There must be one static object
  *  of this class in every object file that makes use of our flyweights in
@@ -204,7 +209,12 @@ public:
        // comparison
        int compare(const ex & other) const;
        bool is_equal(const ex & other) const;
-       bool is_zero() const { extern const ex _ex0; return is_equal(_ex0); }
+       bool is_zero() const { 
+#ifndef _MSC_VER
+         extern const ex _ex0;
+#endif
+         return is_equal(_ex0); 
+       }
        bool is_zero_matrix() const;
        
        // symmetry
index f114c2e..a0ca4cd 100644 (file)
@@ -114,7 +114,7 @@ ex parser::parse_binop_rhs(int expr_prec, ex& lhs)
        }
 }
 
-extern numeric* _num_1_p;
+extern const numeric* _num_1_p;
 
 static ex make_minus_expr(const exvector& args)
 {
index 0674383..16eed69 100644 (file)
@@ -82,8 +82,7 @@ ex parser::parse_paren_expr()
        return e;
 }
 
-extern numeric* _num_1_p;
-extern ex _ex0;
+extern const ex _ex0;
 
 /// unary_expr: [+-] expression
 ex parser::parse_unary_expr()