[PATCH][cln_1-1] Replace (some of) MAYBE_INLINEs with ISO C++ compliant equivalent
ISO C++ demands (in 7.1.2.4) "If a function with external linkage is declared inline in one translation unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required." MAYBE_INLINE violates this requirement. Moreover, it's pointless, since the compiler emits those functions anyway. This causes link errors on non-ELF platforms (such as woe32 and Darwin). Hence, I decided to replace MAYBE_INLINE with standard compliant (but more intrusive) code. Only fiew occurences of MAYBE_INLINE have been converted. However, this happens to be enough to build CLN as a woe32 DLL (after massive hacking of build scripts). --- src/complex/transcendental/cl_C_acosh.cc | 7 ++++--- src/complex/transcendental/cl_C_asinh_aux.cc | 11 ++++++----- src/complex/transcendental/cl_C_atanh_aux.cc | 10 ++++++---- src/float/dfloat/misc/cl_DF_signum.cc | 9 +++++++-- src/float/ffloat/misc/cl_FF_signum.cc | 10 ++++++++-- src/float/lfloat/misc/cl_LF_signum.cc | 9 +++++++-- src/float/misc/cl_F_signum.cc | 16 ++++++++++------ src/float/sfloat/misc/cl_SF_signum.cc | 9 +++++++-- src/integer/misc/cl_I_signum.cc | 9 +++++++-- src/integer/ring/cl_I_ring.cc | 5 ++++- src/rational/misc/cl_RA_signum.cc | 10 ++++++++-- src/rational/ring/cl_RA_ring.cc | 5 ++++- src/real/conv/cl_F_from_R_def.cc | 9 +++++++-- src/real/misc/cl_R_signum.cc | 19 ++++++++++++++----- 14 files changed, 99 insertions(+), 39 deletions(-) diff --git a/src/complex/transcendental/cl_C_acosh.cc b/src/complex/transcendental/cl_C_acosh.cc index 8c30669..f92989e 100644 --- a/src/complex/transcendental/cl_C_acosh.cc +++ b/src/complex/transcendental/cl_C_acosh.cc @@ -16,8 +16,9 @@ #include "cl_RA.h" #include "cln/float.h" -#undef MAYBE_INLINE -#define MAYBE_INLINE inline +#define INLINE static inline +#define INLINE_DECL(fcn) inline_ ## fcn +#define REALLY_INLINE __attribute__((always_inline)) #include "cl_F_from_R_def.cc" namespace cln { @@ -78,7 +79,7 @@ const cl_N acosh (const cl_N& z) } if (x < cl_I(-1)) { // x < -1 - var cl_F xf = cl_float(x); + var cl_F xf = inline_cl_float(x); var cl_F& x = xf; // x Float <= -1 // log(sqrt(x^2-1)-x), ein Float >=0, Imaginдrteil pi diff --git a/src/complex/transcendental/cl_C_asinh_aux.cc b/src/complex/transcendental/cl_C_asinh_aux.cc index 572c722..9d772c6 100644 --- a/src/complex/transcendental/cl_C_asinh_aux.cc +++ b/src/complex/transcendental/cl_C_asinh_aux.cc @@ -16,8 +16,9 @@ #include "cl_RA.h" #include "cln/float.h" -#undef MAYBE_INLINE -#define MAYBE_INLINE inline +#define INLINE static inline +#define INLINE_DECL(fcn) inline_ ## fcn +#define REALLY_INLINE __attribute__((always_inline)) #include "cl_F_from_R_def.cc" namespace cln { @@ -89,7 +90,7 @@ const cl_C_R asinh (const cl_R& x, const cl_R& y) return cl_C_R(0,scale_float(pi(),-1)); if (eq(y,-1)) // x=0, y=-1 -> v = -pi/2 return cl_C_R(0,-scale_float(pi(),-1)); - yf = cl_float(y); // y in Float umwandeln + yf = inline_cl_float(y); // y in Float umwandeln } else { DeclareType(cl_RT,y); // y Ratio @@ -99,7 +100,7 @@ const cl_C_R asinh (const cl_R& x, const cl_R& y) if (eq(numerator(y),-1)) // x=0, y=-1/2 -> v = -pi/6 return cl_C_R(0,-(pi()/6)); } - yf = cl_float(y); // y in Float umwandeln + yf = inline_cl_float(y); // y in Float umwandeln } } else { DeclareType(cl_F,y); @@ -135,7 +136,7 @@ const cl_C_R asinh (const cl_R& x, const cl_R& y) } if (eq(y,0)) { // y=0 - var cl_F xf = cl_float(x); // x in Float umwandeln + var cl_F xf = inline_cl_float(x); // x in Float umwandeln var cl_F& x = xf; // x Float if (zerop(x)) diff --git a/src/complex/transcendental/cl_C_atanh_aux.cc b/src/complex/transcendental/cl_C_atanh_aux.cc index 42cae75..90d5205 100644 --- a/src/complex/transcendental/cl_C_atanh_aux.cc +++ b/src/complex/transcendental/cl_C_atanh_aux.cc @@ -14,14 +14,16 @@ #include "cl_F_tran.h" #include "cl_R.h" -#undef MAYBE_INLINE -#define MAYBE_INLINE inline +#define INLINE static inline +#define INLINE_DECL(fcn) inline_ ## fcn +#define REALLY_INLINE __attribute__((always_inline)) #include "cl_F_from_R_def.cc" namespace cln { // Hilfsfunktion fьr atanh und atan: u+iv := artanh(x+iy). Liefert cl_C_R(u,v). +const cl_C_R atanh (const cl_R& x, const cl_R& y) __attribute__((flatten)); const cl_C_R atanh (const cl_R& x, const cl_R& y) { // Methode: @@ -56,7 +58,7 @@ const cl_C_R atanh (const cl_R& x, const cl_R& y) // x=0 -> u=0, v=atan(X=1,Y=y) (Fall y=0 ist inbegriffen) return cl_C_R(0, atan(1,y)); if (eq(y,0)) { - var cl_F xf = cl_float(x); // (float x) + var cl_F xf = inline_cl_float(x); // (float x) var cl_F& x = xf; // x Float if (zerop(x)) @@ -92,7 +94,7 @@ const cl_C_R atanh (const cl_R& x, const cl_R& y) var cl_F yf; if (rationalp(x)) { DeclareType(cl_RA,x); - yf = cl_float(y); + yf = inline_cl_float(y); xf = cl_float(x,yf); } else { DeclareType(cl_F,x); diff --git a/src/float/dfloat/misc/cl_DF_signum.cc b/src/float/dfloat/misc/cl_DF_signum.cc index 3101a93..524ad8f 100644 --- a/src/float/dfloat/misc/cl_DF_signum.cc +++ b/src/float/dfloat/misc/cl_DF_signum.cc @@ -15,11 +15,16 @@ #define MAYBE_INLINE inline #include "cl_DF_minusp.cc" #include "cl_DF_zerop.cc" +#ifndef INLINE2 +#define INLINE2 +#define REALLY_INLINE2 +#define INLINE2_DECL(name) name +#endif namespace cln { -MAYBE_INLINE2 -const cl_DF signum (const cl_DF& x) +INLINE2 const cl_DF INLINE2_DECL(signum) (const cl_DF& x) REALLY_INLINE2; +INLINE2 const cl_DF INLINE2_DECL(signum) (const cl_DF& x) { if (minusp(x)) { return cl_DF_minus1; } // x<0 -> -1.0 elif (zerop(x)) { return cl_DF_0; } // x=0 -> 0.0 diff --git a/src/float/ffloat/misc/cl_FF_signum.cc b/src/float/ffloat/misc/cl_FF_signum.cc index 69cb60e..6816012 100644 --- a/src/float/ffloat/misc/cl_FF_signum.cc +++ b/src/float/ffloat/misc/cl_FF_signum.cc @@ -16,10 +16,16 @@ #include "cl_FF_minusp.cc" #include "cl_FF_zerop.cc" +#ifndef INLINE2 +#define INLINE2 +#define REALLY_INLINE2 +#define INLINE2_DECL(name) name +#endif + namespace cln { -MAYBE_INLINE2 -const cl_FF signum (const cl_FF& x) +INLINE2 const cl_FF INLINE2_DECL(signum) (const cl_FF& x) REALLY_INLINE2; +INLINE2 const cl_FF INLINE2_DECL(signum) (const cl_FF& x) { if (minusp(x)) { return cl_FF_minus1; } // x<0 -> -1.0 elif (zerop(x)) { return cl_FF_0; } // x=0 -> 0.0 diff --git a/src/float/lfloat/misc/cl_LF_signum.cc b/src/float/lfloat/misc/cl_LF_signum.cc index eae4705..a0d31b1 100644 --- a/src/float/lfloat/misc/cl_LF_signum.cc +++ b/src/float/lfloat/misc/cl_LF_signum.cc @@ -16,11 +16,16 @@ #define MAYBE_INLINE inline #include "cl_LF_minusp.cc" #include "cl_LF_zerop.cc" +#ifndef INLINE2 +#define INLINE2 +#define REALLY_INLINE2 +#define INLINE2_DECL(name) name +#endif namespace cln { -MAYBE_INLINE2 -const cl_LF signum (const cl_LF& x) +INLINE2 const cl_LF INLINE2_DECL(signum) (const cl_LF& x) REALLY_INLINE2; +INLINE2 const cl_LF INLINE2_DECL(signum) (const cl_LF& x) { if (zerop(x)) { return x; } // x=0 -> 0.0 else // je nach Vorzeichen von x diff --git a/src/float/misc/cl_F_signum.cc b/src/float/misc/cl_F_signum.cc index 0b51f9e..08ba0b6 100644 --- a/src/float/misc/cl_F_signum.cc +++ b/src/float/misc/cl_F_signum.cc @@ -11,8 +11,12 @@ #include "cl_F.h" -#undef MAYBE_INLINE2 -#define MAYBE_INLINE2 inline +#undef INLINE2 +#undef INLINE2_DECL +#undef REALLY_INLINE2 +#define INLINE2 static inline +#define INLINE2_DECL(name) inline_ ## name +#define REALLY_INLINE2 __attribute__((always_inline)) #include "cl_SF_signum.cc" #include "cl_FF_signum.cc" #include "cl_DF_signum.cc" @@ -23,10 +27,10 @@ namespace cln { const cl_F signum (const cl_F& x) { floatcase(x - , return signum(x); - , return signum(x); - , return signum(x); - , return signum(x); + , return inline_signum(x); + , return inline_signum(x); + , return inline_signum(x); + , return inline_signum(x); ); } diff --git a/src/float/sfloat/misc/cl_SF_signum.cc b/src/float/sfloat/misc/cl_SF_signum.cc index b1239da..1374727 100644 --- a/src/float/sfloat/misc/cl_SF_signum.cc +++ b/src/float/sfloat/misc/cl_SF_signum.cc @@ -15,11 +15,16 @@ #define MAYBE_INLINE inline #include "cl_SF_minusp.cc" #include "cl_SF_zerop.cc" +#ifndef INLINE2 +#define INLINE2 +#define REALLY_INLINE2 +#define INLINE2_DECL(name) name +#endif namespace cln { -MAYBE_INLINE2 -const cl_SF signum (const cl_SF& x) +INLINE2 const cl_SF INLINE2_DECL(signum) (const cl_SF& x) REALLY_INLINE2; +INLINE2 const cl_SF INLINE2_DECL(signum) (const cl_SF& x) { if (minusp(x)) { return SF_minus1; } // x<0 -> -1.0 elif (zerop(x)) { return SF_0; } // x=0 -> 0.0 diff --git a/src/integer/misc/cl_I_signum.cc b/src/integer/misc/cl_I_signum.cc index bbd236a..7a8a8c9 100644 --- a/src/integer/misc/cl_I_signum.cc +++ b/src/integer/misc/cl_I_signum.cc @@ -10,11 +10,16 @@ // Implementation. #include "cl_I.h" +#ifndef INLINE +#define INLINE +#define REALLY_INLINE +#define INLINE_DECL(name) name +#endif namespace cln { -MAYBE_INLINE -const cl_I signum (const cl_I& x) +INLINE const cl_I INLINE_DECL(signum) (const cl_I& x) REALLY_INLINE; +INLINE const cl_I INLINE_DECL(signum) (const cl_I& x) { if (minusp(x)) { return -1; } // x<0 -> -1 elif (zerop(x)) { return 0; } // x=0 -> 0 diff --git a/src/integer/ring/cl_I_ring.cc b/src/integer/ring/cl_I_ring.cc index 0f4e6d7..c8538ef 100644 --- a/src/integer/ring/cl_I_ring.cc +++ b/src/integer/ring/cl_I_ring.cc @@ -13,7 +13,9 @@ CL_PROVIDE(cl_I_ring) #include "cln/integer.h" #include "cln/integer_io.h" +#define zerop inline_zerop #include "cl_I.h" +#undef zerop namespace cln { @@ -34,10 +36,11 @@ static const _cl_ring_element I_zero (cl_heap_ring* R) return _cl_ring_element(R, (cl_I)0); } +static cl_boolean I_zerop (cl_heap_ring* R, const _cl_ring_element& x) __attribute__((flatten)); static cl_boolean I_zerop (cl_heap_ring* R, const _cl_ring_element& x) { unused R; - return zerop(The(cl_I)(x)); + return inline_zerop(The(cl_I)(x)); } static const _cl_ring_element I_plus (cl_heap_ring* R, const _cl_ring_element& x, const _cl_ring_element& y) diff --git a/src/rational/misc/cl_RA_signum.cc b/src/rational/misc/cl_RA_signum.cc index 40f5380..fc80077 100644 --- a/src/rational/misc/cl_RA_signum.cc +++ b/src/rational/misc/cl_RA_signum.cc @@ -11,11 +11,17 @@ #include "cl_RA.h" #include "cl_I.h" +#ifndef INLINE +#define INLINE +#define REALLY_INLINE +#define INLINE_DECL(name) name +#endif + namespace cln { -MAYBE_INLINE -const cl_RA signum (const cl_RA& x) +INLINE const cl_RA INLINE_DECL(signum) (const cl_RA& x) REALLY_INLINE; +INLINE const cl_RA INLINE_DECL(signum) (const cl_RA& x) { if (minusp(x)) { return -1; } // x<0 -> -1 elif (zerop(x)) { return 0; } // x=0 -> 0 diff --git a/src/rational/ring/cl_RA_ring.cc b/src/rational/ring/cl_RA_ring.cc index a6aef66..420c87d 100644 --- a/src/rational/ring/cl_RA_ring.cc +++ b/src/rational/ring/cl_RA_ring.cc @@ -13,7 +13,9 @@ CL_PROVIDE(cl_RA_ring) #include "cln/rational.h" #include "cln/rational_io.h" +#define zerop inline_zerop #include "cl_RA.h" +#undef zerop namespace cln { @@ -34,10 +36,11 @@ static const _cl_ring_element RA_zero (cl_heap_ring* R) return _cl_ring_element(R, (cl_RA)0); } +static cl_boolean RA_zerop (cl_heap_ring* R, const _cl_ring_element& x) __attribute__((flatten)); static cl_boolean RA_zerop (cl_heap_ring* R, const _cl_ring_element& x) { unused R; - return zerop(The(cl_RA)(x)); + return inline_zerop(The(cl_RA)(x)); } static const _cl_ring_element RA_plus (cl_heap_ring* R, const _cl_ring_element& x, const _cl_ring_element& y) diff --git a/src/real/conv/cl_F_from_R_def.cc b/src/real/conv/cl_F_from_R_def.cc index 3c8e852..01d1082 100644 --- a/src/real/conv/cl_F_from_R_def.cc +++ b/src/real/conv/cl_F_from_R_def.cc @@ -10,11 +10,16 @@ // Implementation. #include "cl_R.h" +#ifndef INLINE +#define INLINE +#define INLINE_DECL(decl) decl +#define REALLY_INLINE +#endif namespace cln { -MAYBE_INLINE -const cl_F cl_float (const cl_R& x) +INLINE const cl_F INLINE_DECL(cl_float) (const cl_R& x) REALLY_INLINE; +INLINE const cl_F INLINE_DECL(cl_float) (const cl_R& x) { if (rationalp(x)) { DeclareType(cl_RA,x); diff --git a/src/real/misc/cl_R_signum.cc b/src/real/misc/cl_R_signum.cc index f151d6c..b225639 100644 --- a/src/real/misc/cl_R_signum.cc +++ b/src/real/misc/cl_R_signum.cc @@ -11,12 +11,20 @@ #include "cl_R.h" -#undef MAYBE_INLINE -#define MAYBE_INLINE inline +#undef INLINE +#undef REALLY_INLINE +#undef INLINE_DECL +#define INLINE static inline +#define REALLY_INLINE __attribute__((always_inline)) +#define INLINE_DECL(name) inline_ ## name #include "cl_I_signum.cc" #include "cl_RA_signum.cc" -#undef MAYBE_INLINE2 -#define MAYBE_INLINE2 inline +#undef INLINE2 +#undef INLINE2_DECL +#undef REALLY_INLINE2 +#define INLINE2 static inline +#define INLINE2_DECL(name) inline_ ## name +#define REALLY_INLINE2 __attribute__((always_inline)) #include "cl_SF_signum.cc" #include "cl_FF_signum.cc" #include "cl_DF_signum.cc" @@ -24,7 +32,8 @@ namespace cln { +const cl_R signum (const cl_R& x) __attribute__((flatten)); const cl_R signum (const cl_R& x) -GEN_R_OP1_7(x, signum, return) +GEN_R_OP1_7(x, inline_signum, return) } // namespace cln -- 1.5.3.7 Best regards, Alexei -- All science is either physics or stamp collecting.
ISO C++ demands (in 7.1.2.4) "If a function with external linkage is declared inline in one translation unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required." MAYBE_INLINE violates this requirement. Moreover, it's pointless, since the compiler emits those functions anyway. This causes link errors on non-ELF platforms (such as woe32 and Darwin). Hence, I decided to replace MAYBE_INLINE with standard compliant (but more intrusive) code. Only fiew occurences of MAYBE_INLINE have been converted. However, this happens to be enough to build CLN as a woe32 DLL (after massive hacking of build scripts). --- src/complex/transcendental/cl_C_acosh.cc | 7 ++++--- src/complex/transcendental/cl_C_asinh_aux.cc | 11 ++++++----- src/complex/transcendental/cl_C_atanh_aux.cc | 10 ++++++---- src/float/dfloat/misc/cl_DF_signum.cc | 9 +++++++-- src/float/ffloat/misc/cl_FF_signum.cc | 10 ++++++++-- src/float/lfloat/misc/cl_LF_signum.cc | 9 +++++++-- src/float/misc/cl_F_signum.cc | 16 ++++++++++------ src/float/sfloat/misc/cl_SF_signum.cc | 9 +++++++-- src/integer/misc/cl_I_signum.cc | 9 +++++++-- src/integer/ring/cl_I_ring.cc | 5 ++++- src/rational/misc/cl_RA_signum.cc | 10 ++++++++-- src/rational/ring/cl_RA_ring.cc | 5 ++++- src/real/conv/cl_F_from_R_def.cc | 9 +++++++-- src/real/misc/cl_R_signum.cc | 19 ++++++++++++++----- 14 files changed, 99 insertions(+), 39 deletions(-) diff --git a/src/complex/transcendental/cl_C_acosh.cc b/src/complex/transcendental/cl_C_acosh.cc index 2fb952f..79f1f6e 100644 --- a/src/complex/transcendental/cl_C_acosh.cc +++ b/src/complex/transcendental/cl_C_acosh.cc @@ -16,8 +16,9 @@ #include "cl_RA.h" #include "cln/float.h" -#undef MAYBE_INLINE -#define MAYBE_INLINE inline +#define INLINE static inline +#define INLINE_DECL(fcn) inline_ ## fcn +#define REALLY_INLINE __attribute__((always_inline)) #include "cl_F_from_R_def.cc" namespace cln { @@ -78,7 +79,7 @@ const cl_N acosh (const cl_N& z) } if (x < cl_I(-1)) { // x < -1 - var cl_F xf = cl_float(x); + var cl_F xf = inline_cl_float(x); var cl_F& x = xf; // x Float <= -1 // log(sqrt(x^2-1)-x), ein Float >=0, Imaginärteil pi diff --git a/src/complex/transcendental/cl_C_asinh_aux.cc b/src/complex/transcendental/cl_C_asinh_aux.cc index 623ab30..62f4c67 100644 --- a/src/complex/transcendental/cl_C_asinh_aux.cc +++ b/src/complex/transcendental/cl_C_asinh_aux.cc @@ -16,8 +16,9 @@ #include "cl_RA.h" #include "cln/float.h" -#undef MAYBE_INLINE -#define MAYBE_INLINE inline +#define INLINE static inline +#define INLINE_DECL(fcn) inline_ ## fcn +#define REALLY_INLINE __attribute__((always_inline)) #include "cl_F_from_R_def.cc" namespace cln { @@ -89,7 +90,7 @@ const cl_C_R asinh (const cl_R& x, const cl_R& y) return cl_C_R(0,scale_float(pi(),-1)); if (eq(y,-1)) // x=0, y=-1 -> v = -pi/2 return cl_C_R(0,-scale_float(pi(),-1)); - yf = cl_float(y); // y in Float umwandeln + yf = inline_cl_float(y); // y in Float umwandeln } else { DeclareType(cl_RT,y); // y Ratio @@ -99,7 +100,7 @@ const cl_C_R asinh (const cl_R& x, const cl_R& y) if (eq(numerator(y),-1)) // x=0, y=-1/2 -> v = -pi/6 return cl_C_R(0,-(pi()/6)); } - yf = cl_float(y); // y in Float umwandeln + yf = inline_cl_float(y); // y in Float umwandeln } } else { DeclareType(cl_F,y); @@ -135,7 +136,7 @@ const cl_C_R asinh (const cl_R& x, const cl_R& y) } if (eq(y,0)) { // y=0 - var cl_F xf = cl_float(x); // x in Float umwandeln + var cl_F xf = inline_cl_float(x); // x in Float umwandeln var cl_F& x = xf; // x Float if (zerop(x)) diff --git a/src/complex/transcendental/cl_C_atanh_aux.cc b/src/complex/transcendental/cl_C_atanh_aux.cc index 2435495..4c8af8d 100644 --- a/src/complex/transcendental/cl_C_atanh_aux.cc +++ b/src/complex/transcendental/cl_C_atanh_aux.cc @@ -14,14 +14,16 @@ #include "cl_F_tran.h" #include "cl_R.h" -#undef MAYBE_INLINE -#define MAYBE_INLINE inline +#define INLINE static inline +#define INLINE_DECL(fcn) inline_ ## fcn +#define REALLY_INLINE __attribute__((always_inline)) #include "cl_F_from_R_def.cc" namespace cln { // Hilfsfunktion für atanh und atan: u+iv := artanh(x+iy). Liefert cl_C_R(u,v). +const cl_C_R atanh (const cl_R& x, const cl_R& y) __attribute__((flatten)); const cl_C_R atanh (const cl_R& x, const cl_R& y) { // Methode: @@ -56,7 +58,7 @@ const cl_C_R atanh (const cl_R& x, const cl_R& y) // x=0 -> u=0, v=atan(X=1,Y=y) (Fall y=0 ist inbegriffen) return cl_C_R(0, atan(1,y)); if (eq(y,0)) { - var cl_F xf = cl_float(x); // (float x) + var cl_F xf = inline_cl_float(x); // (float x) var cl_F& x = xf; // x Float if (zerop(x)) @@ -92,7 +94,7 @@ const cl_C_R atanh (const cl_R& x, const cl_R& y) var cl_F yf; if (rationalp(x)) { DeclareType(cl_RA,x); - yf = cl_float(y); + yf = inline_cl_float(y); xf = cl_float(x,yf); } else { DeclareType(cl_F,x); diff --git a/src/float/dfloat/misc/cl_DF_signum.cc b/src/float/dfloat/misc/cl_DF_signum.cc index 3101a93..524ad8f 100644 --- a/src/float/dfloat/misc/cl_DF_signum.cc +++ b/src/float/dfloat/misc/cl_DF_signum.cc @@ -15,11 +15,16 @@ #define MAYBE_INLINE inline #include "cl_DF_minusp.cc" #include "cl_DF_zerop.cc" +#ifndef INLINE2 +#define INLINE2 +#define REALLY_INLINE2 +#define INLINE2_DECL(name) name +#endif namespace cln { -MAYBE_INLINE2 -const cl_DF signum (const cl_DF& x) +INLINE2 const cl_DF INLINE2_DECL(signum) (const cl_DF& x) REALLY_INLINE2; +INLINE2 const cl_DF INLINE2_DECL(signum) (const cl_DF& x) { if (minusp(x)) { return cl_DF_minus1; } // x<0 -> -1.0 elif (zerop(x)) { return cl_DF_0; } // x=0 -> 0.0 diff --git a/src/float/ffloat/misc/cl_FF_signum.cc b/src/float/ffloat/misc/cl_FF_signum.cc index 69cb60e..6816012 100644 --- a/src/float/ffloat/misc/cl_FF_signum.cc +++ b/src/float/ffloat/misc/cl_FF_signum.cc @@ -16,10 +16,16 @@ #include "cl_FF_minusp.cc" #include "cl_FF_zerop.cc" +#ifndef INLINE2 +#define INLINE2 +#define REALLY_INLINE2 +#define INLINE2_DECL(name) name +#endif + namespace cln { -MAYBE_INLINE2 -const cl_FF signum (const cl_FF& x) +INLINE2 const cl_FF INLINE2_DECL(signum) (const cl_FF& x) REALLY_INLINE2; +INLINE2 const cl_FF INLINE2_DECL(signum) (const cl_FF& x) { if (minusp(x)) { return cl_FF_minus1; } // x<0 -> -1.0 elif (zerop(x)) { return cl_FF_0; } // x=0 -> 0.0 diff --git a/src/float/lfloat/misc/cl_LF_signum.cc b/src/float/lfloat/misc/cl_LF_signum.cc index eae4705..a0d31b1 100644 --- a/src/float/lfloat/misc/cl_LF_signum.cc +++ b/src/float/lfloat/misc/cl_LF_signum.cc @@ -16,11 +16,16 @@ #define MAYBE_INLINE inline #include "cl_LF_minusp.cc" #include "cl_LF_zerop.cc" +#ifndef INLINE2 +#define INLINE2 +#define REALLY_INLINE2 +#define INLINE2_DECL(name) name +#endif namespace cln { -MAYBE_INLINE2 -const cl_LF signum (const cl_LF& x) +INLINE2 const cl_LF INLINE2_DECL(signum) (const cl_LF& x) REALLY_INLINE2; +INLINE2 const cl_LF INLINE2_DECL(signum) (const cl_LF& x) { if (zerop(x)) { return x; } // x=0 -> 0.0 else // je nach Vorzeichen von x diff --git a/src/float/misc/cl_F_signum.cc b/src/float/misc/cl_F_signum.cc index 0b51f9e..08ba0b6 100644 --- a/src/float/misc/cl_F_signum.cc +++ b/src/float/misc/cl_F_signum.cc @@ -11,8 +11,12 @@ #include "cl_F.h" -#undef MAYBE_INLINE2 -#define MAYBE_INLINE2 inline +#undef INLINE2 +#undef INLINE2_DECL +#undef REALLY_INLINE2 +#define INLINE2 static inline +#define INLINE2_DECL(name) inline_ ## name +#define REALLY_INLINE2 __attribute__((always_inline)) #include "cl_SF_signum.cc" #include "cl_FF_signum.cc" #include "cl_DF_signum.cc" @@ -23,10 +27,10 @@ namespace cln { const cl_F signum (const cl_F& x) { floatcase(x - , return signum(x); - , return signum(x); - , return signum(x); - , return signum(x); + , return inline_signum(x); + , return inline_signum(x); + , return inline_signum(x); + , return inline_signum(x); ); } diff --git a/src/float/sfloat/misc/cl_SF_signum.cc b/src/float/sfloat/misc/cl_SF_signum.cc index b1239da..1374727 100644 --- a/src/float/sfloat/misc/cl_SF_signum.cc +++ b/src/float/sfloat/misc/cl_SF_signum.cc @@ -15,11 +15,16 @@ #define MAYBE_INLINE inline #include "cl_SF_minusp.cc" #include "cl_SF_zerop.cc" +#ifndef INLINE2 +#define INLINE2 +#define REALLY_INLINE2 +#define INLINE2_DECL(name) name +#endif namespace cln { -MAYBE_INLINE2 -const cl_SF signum (const cl_SF& x) +INLINE2 const cl_SF INLINE2_DECL(signum) (const cl_SF& x) REALLY_INLINE2; +INLINE2 const cl_SF INLINE2_DECL(signum) (const cl_SF& x) { if (minusp(x)) { return SF_minus1; } // x<0 -> -1.0 elif (zerop(x)) { return SF_0; } // x=0 -> 0.0 diff --git a/src/integer/misc/cl_I_signum.cc b/src/integer/misc/cl_I_signum.cc index bbd236a..7a8a8c9 100644 --- a/src/integer/misc/cl_I_signum.cc +++ b/src/integer/misc/cl_I_signum.cc @@ -10,11 +10,16 @@ // Implementation. #include "cl_I.h" +#ifndef INLINE +#define INLINE +#define REALLY_INLINE +#define INLINE_DECL(name) name +#endif namespace cln { -MAYBE_INLINE -const cl_I signum (const cl_I& x) +INLINE const cl_I INLINE_DECL(signum) (const cl_I& x) REALLY_INLINE; +INLINE const cl_I INLINE_DECL(signum) (const cl_I& x) { if (minusp(x)) { return -1; } // x<0 -> -1 elif (zerop(x)) { return 0; } // x=0 -> 0 diff --git a/src/integer/ring/cl_I_ring.cc b/src/integer/ring/cl_I_ring.cc index 416738a..c827b34 100644 --- a/src/integer/ring/cl_I_ring.cc +++ b/src/integer/ring/cl_I_ring.cc @@ -13,7 +13,9 @@ CL_PROVIDE(cl_I_ring) #include "cln/integer.h" #include "cln/integer_io.h" +#define zerop inline_zerop #include "cl_I.h" +#undef zerop namespace cln { @@ -34,10 +36,11 @@ static const _cl_ring_element I_zero (cl_heap_ring* R) return _cl_ring_element(R, (cl_I)0); } +static bool I_zerop (cl_heap_ring* R, const _cl_ring_element& x) __attribute((flatten)); static bool I_zerop (cl_heap_ring* R, const _cl_ring_element& x) { unused R; - return zerop(The(cl_I)(x)); + return inline_zerop(The(cl_I)(x)); } static const _cl_ring_element I_plus (cl_heap_ring* R, const _cl_ring_element& x, const _cl_ring_element& y) diff --git a/src/rational/misc/cl_RA_signum.cc b/src/rational/misc/cl_RA_signum.cc index 40f5380..fc80077 100644 --- a/src/rational/misc/cl_RA_signum.cc +++ b/src/rational/misc/cl_RA_signum.cc @@ -11,11 +11,17 @@ #include "cl_RA.h" #include "cl_I.h" +#ifndef INLINE +#define INLINE +#define REALLY_INLINE +#define INLINE_DECL(name) name +#endif + namespace cln { -MAYBE_INLINE -const cl_RA signum (const cl_RA& x) +INLINE const cl_RA INLINE_DECL(signum) (const cl_RA& x) REALLY_INLINE; +INLINE const cl_RA INLINE_DECL(signum) (const cl_RA& x) { if (minusp(x)) { return -1; } // x<0 -> -1 elif (zerop(x)) { return 0; } // x=0 -> 0 diff --git a/src/rational/ring/cl_RA_ring.cc b/src/rational/ring/cl_RA_ring.cc index e7d33f3..eb47000 100644 --- a/src/rational/ring/cl_RA_ring.cc +++ b/src/rational/ring/cl_RA_ring.cc @@ -13,7 +13,9 @@ CL_PROVIDE(cl_RA_ring) #include "cln/rational.h" #include "cln/rational_io.h" +#define zerop inline_zerop #include "cl_RA.h" +#undef zerop namespace cln { @@ -34,10 +36,11 @@ static const _cl_ring_element RA_zero (cl_heap_ring* R) return _cl_ring_element(R, (cl_RA)0); } +static bool RA_zerop (cl_heap_ring* R, const _cl_ring_element& x) __attribute__((flatten)); static bool RA_zerop (cl_heap_ring* R, const _cl_ring_element& x) { unused R; - return zerop(The(cl_RA)(x)); + return inline_zerop(The(cl_RA)(x)); } static const _cl_ring_element RA_plus (cl_heap_ring* R, const _cl_ring_element& x, const _cl_ring_element& y) diff --git a/src/real/conv/cl_F_from_R_def.cc b/src/real/conv/cl_F_from_R_def.cc index 3c8e852..01d1082 100644 --- a/src/real/conv/cl_F_from_R_def.cc +++ b/src/real/conv/cl_F_from_R_def.cc @@ -10,11 +10,16 @@ // Implementation. #include "cl_R.h" +#ifndef INLINE +#define INLINE +#define INLINE_DECL(decl) decl +#define REALLY_INLINE +#endif namespace cln { -MAYBE_INLINE -const cl_F cl_float (const cl_R& x) +INLINE const cl_F INLINE_DECL(cl_float) (const cl_R& x) REALLY_INLINE; +INLINE const cl_F INLINE_DECL(cl_float) (const cl_R& x) { if (rationalp(x)) { DeclareType(cl_RA,x); diff --git a/src/real/misc/cl_R_signum.cc b/src/real/misc/cl_R_signum.cc index f151d6c..b225639 100644 --- a/src/real/misc/cl_R_signum.cc +++ b/src/real/misc/cl_R_signum.cc @@ -11,12 +11,20 @@ #include "cl_R.h" -#undef MAYBE_INLINE -#define MAYBE_INLINE inline +#undef INLINE +#undef REALLY_INLINE +#undef INLINE_DECL +#define INLINE static inline +#define REALLY_INLINE __attribute__((always_inline)) +#define INLINE_DECL(name) inline_ ## name #include "cl_I_signum.cc" #include "cl_RA_signum.cc" -#undef MAYBE_INLINE2 -#define MAYBE_INLINE2 inline +#undef INLINE2 +#undef INLINE2_DECL +#undef REALLY_INLINE2 +#define INLINE2 static inline +#define INLINE2_DECL(name) inline_ ## name +#define REALLY_INLINE2 __attribute__((always_inline)) #include "cl_SF_signum.cc" #include "cl_FF_signum.cc" #include "cl_DF_signum.cc" @@ -24,7 +32,8 @@ namespace cln { +const cl_R signum (const cl_R& x) __attribute__((flatten)); const cl_R signum (const cl_R& x) -GEN_R_OP1_7(x, signum, return) +GEN_R_OP1_7(x, inline_signum, return) } // namespace cln -- 1.5.3.7 Best regards, Alexei -- All science is either physics or stamp collecting.
Dear Alexei, Alexei Sheplyakov wrote:
ISO C++ demands (in 7.1.2.4) "If a function with external linkage is declared inline in one translation unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required." MAYBE_INLINE violates this requirement. Moreover, it's pointless, since the compiler emits those functions anyway. This causes link errors on non-ELF platforms (such as woe32 and Darwin). Hence, I decided to replace MAYBE_INLINE with standard compliant (but more intrusive) code. Only fiew occurences of MAYBE_INLINE have been converted. However, this happens to be enough to build CLN as a woe32 DLL (after massive hacking of build scripts).
Ouch, that patch is ugly as sin. But if, as a consequence, it will help someone provide DLLs of CLN, well, then maybe it should be applied. However, I'm worried about the maintainability: Can you, please, write a comment explaining what you're doing at some suitable place in the sources? And, can you please provide a ChangeLog entry for all that? (Oh, and don't worry about that cln_1-1 branch: I'll release CLN 1.2.0 really soon now.) And one last question: Do you have any idea why it's enough converting only these few occurrences? Cheers -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/>
Hello Richard,
Ouch, that patch is ugly as sin.
I like Alexei's patch. - As I understand, it fixes the problem. - It does not introduce code duplication in the source code. The only thing I would change about it is that I would use ##_inline as a suffix, rather than inline_## as a prefix - because in CLN the prefix is traditionally the number type (I_, RA_ etc.). Yes, some comments about it are needed. Bruno
Hello! On Thu, Jan 10, 2008 at 11:54:46PM +0100, Richard B. Kreckel wrote:
Ouch, that patch is ugly as sin.
Unfortunately, this ugliness is imposed by the standard (ANSI C++).
But if, as a consequence, it will help someone provide DLLs of CLN, well, then maybe it should be applied.
The patch gets rid of some standard violating code. As a consequence, it helps me to provide DLLs [1].
However, I'm worried about the maintainability: Can you, please, write a comment explaining what you're doing at some suitable place in the sources?
Non-diff part of my previous email is supposed to explain the patch. I'm afraid more details will only obfuscate the source. Anyway, here it is: CLN wants to inline some functions in some places and not in others. The reasons to do so are explained here: http://www.ginac.de/pipermail/ginac-list/2003-November/000433.html However, MAYBE_INLINE thing is a wrong way. First of all, the `inline' keyword is only a recommendation, not an order. The compiler is free to not inline a function (IMHO its decisions are correct more often than not). And this is what actually happens, see, e.g. http://www.ginac.de/pipermail/cln-list/2007-October/000317.html As a side note, the compiler is free to inline functions even if it is NOT marked as inline (this can be disabled with __attribute__((noinline)) in GNU C/C++). Secondly, in ANSI C++ a function *must* be either inline in *every* translation unit, or non-inline in *every* translation unit. Hence, MAYBE_INLINE is not valid C++ (although it's valid C). The compiler does not check for violations of this rule (as per standard), so MAYBE_INLINE kind of works on some platforms (and some versions of the GNU compiler and some misterious compiler/linker flags. This is not speculation, I used to get bizzare link errors even on Linux with g++ 3.3 and CXXFLAGS="-O2 -mcpu=ev6"). The patch renames internal versions of "simple" functions and makes them (static) inline. Thus, the code does not violate the standard, and link errors don't happen. However, everything comes at a price. It's necessary to replace almost every invocation of a function `foo' with `inline_foo'. That `almost' is the worse thing: in some places `foo' should NOT be renamed to `inline_foo'. This is ugly, but I don't see any better *standard-compliant* way to achive the goal. Does this explantion sound any better? Is it OK to include it in the code?
(Oh, and don't worry about that cln_1-1 branch: I'll release CLN 1.2.0 really soon now.)
The patch was written specifically for CLN version 1.1, since I use that version of CLN (I'm not going to upgrade anytime soon). I've forward ported it to the development branch (that take me less than 5 minutes).
And one last question: Do you have any idea why it's enough converting only these few occurrences?
In all of these cases inlining the function in question is very difficult or even impossible. The most obvious is zerop. In cl_I_ring.cc 112 static cl_number_ring_ops<cl_I> I_ops = { 113 cl_I_p, 114 equal, 115 zerop, 116 operator+, 117 operator-, 118 operator-, 119 operator*, 120 square, 121 expt_pos 122 }; Here, the address of zerop is taken, hence, the compiler is forced to emit out-of-line copy. The same applies to cl_RA_ring.cc Other cases are more difficult to analyse. Anyway, the compiler is free to NOT inline functions, and the code[r] should cope with that. Best regards, Alexei [1] http://theor.jinr.ru/~varg/web/proj/ginac/woe32 -- All science is either physics or stamp collecting.
Dear Alexei, Alexei Sheplyakov wrote:
Ouch, that patch is ugly as sin.
Unfortunately, this ugliness is imposed by the standard (ANSI C++).
Yes, I'm aware of that.
Non-diff part of my previous email is supposed to explain the patch. I'm afraid more details will only obfuscate the source. Anyway, here it is:
CLN wants to inline some functions in some places and not in others. The reasons to do so are explained here: http://www.ginac.de/pipermail/ginac-list/2003-November/000433.html
However, MAYBE_INLINE thing is a wrong way. First of all, the `inline' keyword is only a recommendation, not an order. The compiler is free to not inline a function (IMHO its decisions are correct more often than not). And this is what actually happens, see, e.g.
http://www.ginac.de/pipermail/cln-list/2007-October/000317.html
As a side note, the compiler is free to inline functions even if it is NOT marked as inline (this can be disabled with __attribute__((noinline)) in GNU C/C++).
Secondly, in ANSI C++ a function *must* be either inline in *every* translation unit, or non-inline in *every* translation unit. Hence, MAYBE_INLINE is not valid C++ (although it's valid C). The compiler does not check for violations of this rule (as per standard), so MAYBE_INLINE kind of works on some platforms (and some versions of the GNU compiler and some misterious compiler/linker flags. This is not speculation, I used to get bizzare link errors even on Linux with g++ 3.3 and CXXFLAGS="-O2 -mcpu=ev6").
The patch renames internal versions of "simple" functions and makes them (static) inline. Thus, the code does not violate the standard, and link errors don't happen. However, everything comes at a price. It's necessary to replace almost every invocation of a function `foo' with `inline_foo'. That `almost' is the worse thing: in some places `foo' should NOT be renamed to `inline_foo'. This is ugly, but I don't see any better *standard-compliant* way to achive the goal.
Does this explantion sound any better? Is it OK to include it in the code?
Yes, thanks a lot. But I'm still having a hard time understanding how the combination of attributes 'flatten' and 'always_inline' work out. Please put in a little comment about that, directly at the point of definition in the source code. It would be quite helpful, I think. Can you, please, do this and also incorporate Bruno's suggestion, then resend the entire patch? I'm waiting with the release until this is checked in. Thanks a lot!
And one last question: Do you have any idea why it's enough converting only these few occurrences?
In all of these cases inlining the function in question is very difficult or even impossible.
The most obvious is zerop. In cl_I_ring.cc
112 static cl_number_ring_ops<cl_I> I_ops = { 113 cl_I_p, 114 equal, 115 zerop, 116 operator+, 117 operator-, 118 operator-, 119 operator*, 120 square, 121 expt_pos 122 };
Here, the address of zerop is taken, hence, the compiler is forced to emit out-of-line copy. The same applies to cl_RA_ring.cc
Aha, thank you. Cheers -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/>
Dear Richard, On Sat, Jan 12, 2008 at 12:59:27AM +0100, Richard B. Kreckel wrote:
But I'm still having a hard time understanding how the combination of attributes 'flatten' and 'always_inline' work out.
These attributes make the compiler inline functions more aggressively, so no out of line copies (which cause link failure) produced.
Please put in a little comment about that, directly at the point of definition in the source code. It would be quite helpful, I think.
OK.
Can you, please, do this and also incorporate Bruno's suggestion, then resend the entire patch?
I found out my patch was incomplete. In some places non-inline versions of functions was used intstead of inline ones. In principle, they never got inlined anyway (this was exactly the reason of linker errors, and that's why I made the patch in first place). I've tried to replace MAYBE_INLINE the Right Way (TM), however, it turned out to be somewhat difficult. I.e. it's possible to replace either all of MAYBE_INLINEs or none of them. Thus, the correct patch would be even more ugly. Also I failed to convert a couple of (most) obscure instances: 1. src/real/misc/cl_R_eqhashcode.cc 20 #include "cl_I_eqhashcode.cc" 21 #include "cl_SF_eqhashcode.cc" 22 #include "cl_FF_eqhashcode.cc" 23 #include "cl_DF_eqhashcode.cc" 24 #include "cl_LF_eqhashcode.cc" Why equal_hashcode(const cl_RA&) is not inlined, but other type-specific equal_hashcode functions are? 2. src/rational/misc/cl_RA_eqhashcode.cc Why equal_hashcode(const cl_I&) is not inlined? 3. include/cln/float.h 23 struct cl_idecoded_float { 24 cl_I mantissa; 25 cl_I exponent; 26 cl_I sign; 27 // Constructor. 28 cl_idecoded_float () {} 29 cl_idecoded_float (const cl_I& m, const cl_I& e, const cl_I& s) : mantissa(m), exponent(e), sign(s) {} 30 }; Why sign is cl_I? It looks like bool would be enough. 4. src/base/string/cl_st_concat2.cc Why it is necessary to inline cl_make_heap_string? Is it really performance critical? And why CLN needs its own type for strings, what's wrong with std::string? Best regards, Alexei -- All science is either physics or stamp collecting.
Dear Alexei, Alexei Sheplyakov wrote:
On Sat, Jan 12, 2008 at 12:59:27AM +0100, Richard B. Kreckel wrote:
But I'm still having a hard time understanding how the combination of attributes 'flatten' and 'always_inline' work out.
These attributes make the compiler inline functions more aggressively, so no out of line copies (which cause link failure) produced.
*That* should be explained in source code comments.
Can you, please, do this and also incorporate Bruno's suggestion, then resend the entire patch?
I found out my patch was incomplete.
Which makes me wonder: what's the definition of 'complete', here? Does it work or not? Does it depend on compiler flags like -finline-limit?
In some places non-inline versions of functions was used intstead of inline ones. In principle, they never got inlined anyway (this was exactly the reason of linker errors, and that's why I made the patch in first place). I've tried to replace MAYBE_INLINE the Right Way (TM), however, it turned out to be somewhat difficult. I.e. it's possible to replace either all of MAYBE_INLINEs or none of them. Thus, the correct patch would be even more ugly. Also I failed to convert a couple of (most) obscure instances:
1. src/real/misc/cl_R_eqhashcode.cc
20 #include "cl_I_eqhashcode.cc" 21 #include "cl_SF_eqhashcode.cc" 22 #include "cl_FF_eqhashcode.cc" 23 #include "cl_DF_eqhashcode.cc" 24 #include "cl_LF_eqhashcode.cc"
Why equal_hashcode(const cl_RA&) is not inlined, but other type-specific equal_hashcode functions are?
2. src/rational/misc/cl_RA_eqhashcode.cc
Why equal_hashcode(const cl_I&) is not inlined?
3. include/cln/float.h
23 struct cl_idecoded_float { 24 cl_I mantissa; 25 cl_I exponent; 26 cl_I sign; 27 // Constructor. 28 cl_idecoded_float () {} 29 cl_idecoded_float (const cl_I& m, const cl_I& e, const cl_I& s) : mantissa(m), exponent(e), sign(s) {} 30 };
Why sign is cl_I? It looks like bool would be enough.
Why not cl_I? Remember that small integers are immediate.
4. src/base/string/cl_st_concat2.cc
Why it is necessary to inline cl_make_heap_string? Is it really performance critical? And why CLN needs its own type for strings, what's wrong with std::string?
I've also been pondering the removal of that own string class and replacing it with std::string. But it has never been a priority and the change would be somewhat intrusive. That will have to wait until some time after 1.2.0 now. As to why it is necessary to inline cl_make_heap_string? I can't imagine it is critical. -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/>
Dear Richard, New version of the patch is available at http://theor.jinr.ru/~varg/0001-CL_INLINE-co-ISO-C-compliant-macros-for-sele... It gets rid of MAYBE_INLINE completely. I don't post the patch here, since it's large enough (99k uncompressed). Sorry for that, but replacing MAYBE_INLINE in a gradual manner turned out to be surprisngly difficult, i.e. more difficult than rewriting them all.
These attributes make the compiler inline functions more aggressively, so no out of line copies (which cause link failure) produced.
*That* should be explained in source code comments.
Done. But I think gcc manual explains that even better.
I found out my patch was incomplete.
Which makes me wonder: what's the definition of 'complete', here?
It's explained right in the next sentence:
In some places non-inline versions of functions was used intstead of inline ones.
Does it work or not?
Yes.
Does it depend on compiler flags like -finline-limit?
Yes, because quite a number of MAYBE_INLINE stuff left unchanged (in the previous version). The new version of the patch replaces them all, so the dependence on the compiler flags is not that severe.
Why equal_hashcode(const cl_RA&) is not inlined, but other type-specific equal_hashcode functions are?
The inline version of equal_hashcode(const cl_RA&) is used now.
Why sign is cl_I? It looks like bool would be enough.
Why not cl_I? Remember that small integers are immediate.
Although it doesn't consume more memory, tests on it (i.e. minusp) are more expensive and involve a function call (since the inlined versions are not used). If we care about performance (which is a good idea) using plain bool would be better.
I've also been pondering the removal of that own string class and replacing it with std::string. But it has never been a priority and the change would be somewhat intrusive. That will have to wait until some time after 1.2.0 now.
OK.
As to why it is necessary to inline cl_make_heap_string? I can't imagine it is critical.
So I didn't bother to inline it. Best regards, Alexei -- All science is either physics or stamp collecting.
Dear Alexei, Alexei Sheplyakov wrote:
New version of the patch is available at
http://theor.jinr.ru/~varg/0001-CL_INLINE-co-ISO-C-compliant-macros-for-sele...
It gets rid of MAYBE_INLINE completely. I don't post the patch here, since it's large enough (99k uncompressed). Sorry for that, but replacing MAYBE_INLINE in a gradual manner turned out to be surprisngly difficult, i.e. more difficult than rewriting them all.
Thanks a lot! I'm reviewing it and, so far, it looks good. One question. Your patch did not touch these: rbk@wallace:~/projects/cln-1.2/src$ grep -r inline_ . ./integer/elem/cl_I_minusp.cc:#define minusp inline_minusp ./integer/elem/cl_I_minusp.cc: return inline_minusp(x); ./integer/elem/cl_I_plusp.cc:#define minusp inline_minusp ./integer/elem/cl_I_plusp.cc:#define zerop inline_zerop ./integer/elem/cl_I_plusp.cc: if (inline_minusp(x)) ./integer/elem/cl_I_plusp.cc: elif (inline_zerop(x)) ./integer/elem/cl_I_zerop.cc:#define zerop inline_zerop ./integer/elem/cl_I_zerop.cc: return inline_zerop(x); ./rational/elem/cl_RA_denominator.cc:#define denominator inline_denominator ./rational/elem/cl_RA_denominator.cc: return inline_denominator(r); ./rational/elem/cl_RA_numerator.cc:#define numerator inline_numerator ./rational/elem/cl_RA_numerator.cc: return inline_numerator(r); ./rational/elem/cl_RA_plusp.cc:#define minusp inline_minusp ./rational/elem/cl_RA_plusp.cc:#define zerop inline_zerop ./rational/elem/cl_RA_plusp.cc: if (inline_minusp(x)) ./rational/elem/cl_RA_plusp.cc: elif (inline_zerop(x)) ./rational/elem/cl_RA_zerop.cc:#define zerop inline_zerop ./rational/elem/cl_RA_zerop.cc: return inline_zerop(x); Wouldn't it make sense to convert them to make use of your new inline scheme, too? -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/>
Dear Richard, On Wed, Jan 16, 2008 at 11:22:30PM +0100, Richard B. Kreckel wrote:
Your patch did not touch these:
rbk@wallace:~/projects/cln-1.2/src$ grep -r inline_ .
It requires moving inline versions of zerop and minusp from cl_{I,RA}.h, and changing (quite a number of) files to #include cl_{I,RA}_{zero,minus}p.cc instead of cl_{I,RA}.h. That would make the patch even more ugly, so I'd better do this as a separate patch. Best regards, Alexei -- All science is either physics or stamp collecting.
Dear Alexei, Alexei Sheplyakov wrote:
On Wed, Jan 16, 2008 at 11:22:30PM +0100, Richard B. Kreckel wrote:
Your patch did not touch these:
rbk@wallace:~/projects/cln-1.2/src$ grep -r inline_ .
It requires moving inline versions of zerop and minusp from cl_{I,RA}.h, and changing (quite a number of) files to #include cl_{I,RA}_{zero,minus}p.cc instead of cl_{I,RA}.h. That would make the patch even more ugly, so I'd better do this as a separate patch.
Okay. I mentioned it because it is another case where we are violating the standard: zerop(const cl_I&) is inlined in files including cl_I.h, but we emit a function inside cl_I_zerop.cc, too. Cheers -richy. PS: After your last changes, the patch is not too ugly, after all. With the documentation in cl_maybe_inline.h, it is actually maintainable. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/>
Alexei Sheplyakov wrote:
It requires moving inline versions of zerop and minusp from cl_{I,RA}.h, and changing (quite a number of) files to #include cl_{I,RA}_{zero,minus}p.cc instead of cl_{I,RA}.h. That would make the patch even more ugly, so I'd better do this as a separate patch.
Alexei, now that I committed your last patch: Should I wait for the one for cl_{I,Ra}.h or not? (It shouldn't affect the library's API, and if the last patch solved the linking issues the rest can also wait for the 1.2.1 release, I suppose.) Cheers -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/>
Dear Richard,
Alexei, now that I committed your last patch:
You've forgotten to add the `src/base/string/cl_st_make0.h' file, so the build fails (on any platform).
Should I wait for the one for cl_{I,Ra}.h or not?
I don't think you need to wait.
(It shouldn't affect the library's API, and if the last patch solved the linking issues the rest can also wait for the 1.2.1 release, I suppose.)
Sure. Best regards, Alexei -- All science is either physics or stamp collecting.
participants (3)
-
Alexei Sheplyakov
-
Bruno Haible
-
Richard B. Kreckel