Bug 431436

Summary: 4.0.1.0 fails to build on 32bit openSUSE
Product: [Frameworks and Libraries] SeExpr Reporter: Wolfgang Bauer <wbauer1>
Component: GeneralAssignee: amyspark <amy>
Status: RESOLVED FIXED    
Severity: normal CC: amy
Priority: NOR    
Version First Reported In: unspecified   
Target Milestone: ---   
Platform: Other   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Wolfgang Bauer 2021-01-11 13:23:46 UTC
Compiler errors:
/home/abuild/rpmbuild/BUILD/kseexpr-4.0.1.0/src/KSeExprUI/ControlSpec.cpp: In constructor 'KSeExpr::ExprScalarAssignSpec::ExprScalarAssignSpec(const KSeExpr::ExprAssignNode&)':
/home/abuild/rpmbuild/BUILD/kseexpr-4.0.1.0/src/KSeExprUI/ControlSpec.cpp:89:66: error: no matching function for call to 'parseRangeComment(std::string&, float&, float&)'
   89 |         if (KSeExpr::Utils::parseRangeComment(comment, fmin, fmax)) {
      |                                                                  ^

/home/abuild/rpmbuild/BUILD/kseexpr-4.0.1.0/src/KSeExprUI/Editable.cpp: In member function 'virtual bool NumberEditable::parseComment(const string&)':
/home/abuild/rpmbuild/BUILD/kseexpr-4.0.1.0/src/KSeExprUI/Editable.cpp:51:66: error: no matching function for call to 'parseRangeComment(const string&, float&, float&)'
   51 |         if (KSeExpr::Utils::parseRangeComment(comment, fmin, fmax)) {
      |                                                                  ^

Obviously the problem is that KSeExpr::Utils::parseRangeComment is called with `float` parameters, but only accepts `float_t` which apparently is defined different to `float` in 32bit openSUSE Tumbleweed.

Changing `float_t` to `float`, i.e.:
sed -i 's/float_t/float/g' src/KSeExprUI/Utils.cpp
sed -i 's/float_t/float/g' src/KSeExprUI/Utils.h
 fixes the problem, it also still builds fine on 64bit.
Comment 1 Wolfgang Bauer 2021-01-11 13:29:35 UTC
PS: one example how KSeExpr::Utils::parseRangeComment() is called from  src/KSeExprUI/Editable.cpp, line#49ff.:
        float fmin = NAN;
        float fmax = NAN;
        if (KSeExpr::Utils::parseRangeComment(comment, fmin, fmax)) {

And the declaration in src/KSeExprUI/Utils.cpp:
        bool parseRangeComment(const std::string &comment, double_t &from, double_t &to);
        bool parseRangeComment(const std::string &comment, float_t &from, float_t &to);
        bool parseRangeComment(const std::string &comment, int32_t &from, int32_t &to);
Comment 2 Wolfgang Bauer 2021-01-13 12:25:19 UTC
PS: changing the type to float_t in the callers instead doesn't help, I get a different error then:
/home/abuild/rpmbuild/BUILD/kseexpr-4.0.1.0/src/KSeExprUI/Utils.cpp:37:6: error: redefinition of 'bool KSeExpr::Utils::parseRangeComment(const string&, float_t&, float_t&)'
   37 | bool KSeExpr::Utils::parseRangeComment(const std::string &comment, float_t &from, float_t &to)
      |      ^~~~~~~
/home/abuild/rpmbuild/BUILD/kseexpr-4.0.1.0/src/KSeExprUI/Utils.cpp:7:6: note: 'bool KSeExpr::Utils::parseRangeComment(const string&, double_t&, double_t&)' previously defined here
    7 | bool KSeExpr::Utils::parseRangeComment(const std::string &comment, double_t &from, double_t &to)
      |      ^~~~~~~

So it seems that float_t is actually the same as double_t on i586 (apparently both are long double), and therefore the compiler can't decide which one to use...

FTR, this is how the types are defined in /usr/include/math.h here:
# if __GLIBC_FLT_EVAL_METHOD == 0 || __GLIBC_FLT_EVAL_METHOD == 16
typedef float float_t;
typedef double double_t;
# elif __GLIBC_FLT_EVAL_METHOD == 1
typedef double float_t;
typedef double double_t;
# elif __GLIBC_FLT_EVAL_METHOD == 2
typedef long double float_t;
typedef long double double_t;
# elif __GLIBC_FLT_EVAL_METHOD == 32
typedef _Float32 float_t;
typedef double double_t;
# elif __GLIBC_FLT_EVAL_METHOD == 33
typedef _Float32x float_t;
typedef _Float32x double_t;
# elif __GLIBC_FLT_EVAL_METHOD == 64
typedef _Float64 float_t;
typedef _Float64 double_t;
# elif __GLIBC_FLT_EVAL_METHOD == 65
typedef _Float64x float_t;
typedef _Float64x double_t;
# elif __GLIBC_FLT_EVAL_METHOD == 128
typedef _Float128 float_t;
typedef _Float128 double_t;
# elif __GLIBC_FLT_EVAL_METHOD == 129
typedef _Float128x float_t;
typedef _Float128x double_t;
# else
#  error "Unknown __GLIBC_FLT_EVAL_METHOD"
# endif
#endif

and from /usr/include/bits/flt-eval-method.h:
#ifdef __FLT_EVAL_METHOD__
# if __FLT_EVAL_METHOD__ == -1
#  define __GLIBC_FLT_EVAL_METHOD       2
# else
#  define __GLIBC_FLT_EVAL_METHOD       __FLT_EVAL_METHOD__
# endif
#elif defined __x86_64__
# define __GLIBC_FLT_EVAL_METHOD        0
#else
# define __GLIBC_FLT_EVAL_METHOD        2
#endif

=> __GLIBC_FLT_EVAL_METHOD is 2 on i586, leading to both float_t and double_t being long double.

The same problem might occur on certain other architectures or compilers as well, I suppose.
Quoting from https://en.cppreference.com/w/c/numeric/math/float_t:
> The types float_t and double_t are floating types at least as wide as float and 
> double, respectively, and such that double_t is at least as wide as float_t.
> The value of FLT_EVAL_METHOD determines the types of float_t and double_t.
> FLT_EVAL_METHOD	 Explanation
> 0	float_t and double_t are equivalent to float and double, respectively
> 1	 both float_t and double_t are equivalent to double
> 2	 both float_t and double_t are equivalent to long double
> other	 both float_t and double_t are implementation defined
Comment 3 amyspark 2021-06-28 23:47:16 UTC
Git commit de995cff146ce8811be0d1638214911600d499c4 by L. E. Segovia.
Committed on 28/06/2021 at 20:17.
Pushed by lsegovia into branch 'master'.

Do not use float/double_t types for C++17 utils

On very old (i586) architectures, both types are the same.

M  +2    -2    src/KSeExprUI/Utils.cpp
M  +2    -2    src/KSeExprUI/Utils.h

https://invent.kde.org/graphics/kseexpr/commit/de995cff146ce8811be0d1638214911600d499c4
Comment 4 Wolfgang Bauer 2021-06-29 20:19:22 UTC
Sorry, but it still fails:
[  140s] /home/abuild/rpmbuild/BUILD/kseexpr-4.0.2.0/src/KSeExprUI/ControlSpec.cpp: In constructor 'KSeExpr::ExprScalarAssignSpec::ExprScalarAssignSpec(const KSeExpr::ExprAssignNode&)':
[  140s] /home/abuild/rpmbuild/BUILD/kseexpr-4.0.2.0/src/KSeExprUI/ControlSpec.cpp:89:62: error: cannot bind non-const lvalue reference of type 'float_t&' {aka 'long double&'} to a value of type 'float'
[  140s]    89 |         if (KSeExpr::Utils::parseRangeComment(comment, fmin, fmax)) {
[  140s]       |                                                              ^~~~
[  140s] In file included from /home/abuild/rpmbuild/BUILD/kseexpr-4.0.2.0/src/KSeExprUI/ControlSpec.cpp:11:
[  140s] /home/abuild/rpmbuild/BUILD/kseexpr-4.0.2.0/src/KSeExprUI/Utils.h:14:82: note:   initializing argument 3 of 'bool KSeExpr::Utils::parseRangeComment(const string&, float&, float_t&)'
[  140s]    14 |         bool parseRangeComment(const std::string &comment, float &from, float_t &to);
[  140s]       |                                                                         ~~~~~~~~~^~
[  140s] /home/abuild/rpmbuild/BUILD/kseexpr-4.0.2.0/src/KSeExprUI/ControlSpec.cpp: In constructor 'KSeExpr::ExprVectorAssignSpec::ExprVectorAssignSpec(const KSeExpr::ExprAssignNode&)':
[  140s] /home/abuild/rpmbuild/BUILD/kseexpr-4.0.2.0/src/KSeExprUI/ControlSpec.cpp:135:62: error: cannot bind non-const lvalue reference of type 'float_t&' {aka 'long double&'} to a value of type 'float'
[  140s]   135 |         if (KSeExpr::Utils::parseRangeComment(comment, fmin, fmax)) {
[  140s]       |                                                              ^~~~
[  140s] In file included from /home/abuild/rpmbuild/BUILD/kseexpr-4.0.2.0/src/KSeExprUI/ControlSpec.cpp:11:
[  140s] /home/abuild/rpmbuild/BUILD/kseexpr-4.0.2.0/src/KSeExprUI/Utils.h:14:82: note:   initializing argument 3 of 'bool KSeExpr::Utils::parseRangeComment(const string&, float&, float_t&)'
[  140s]    14 |         bool parseRangeComment(const std::string &comment, float &from, float_t &to);
[  140s]       |                                                                         ~~~~~~~~~^~

and:
[  141s] /home/abuild/rpmbuild/BUILD/kseexpr-4.0.2.0/src/KSeExprUI/Editable.cpp: In member function 'virtual bool NumberEditable::parseComment(const string&)':
[  141s] /home/abuild/rpmbuild/BUILD/kseexpr-4.0.2.0/src/KSeExprUI/Editable.cpp:51:62: error: cannot bind non-const lvalue reference of type 'float_t&' {aka 'long double&'} to a value of type 'float'
[  141s]    51 |         if (KSeExpr::Utils::parseRangeComment(comment, fmin, fmax)) {
[  141s]       |                                                              ^~~~
[  141s] In file included from /home/abuild/rpmbuild/BUILD/kseexpr-4.0.2.0/src/KSeExprUI/Editable.cpp:17:
[  141s] /home/abuild/rpmbuild/BUILD/kseexpr-4.0.2.0/src/KSeExprUI/Utils.h:14:82: note:   initializing argument 3 of 'bool KSeExpr::Utils::parseRangeComment(const string&, float&, float_t&)'
[  141s]    14 |         bool parseRangeComment(const std::string &comment, float &from, float_t &to);
[  141s]       |                                                                         ~~~~~~~~~^~
[  141s] /home/abuild/rpmbuild/BUILD/kseexpr-4.0.2.0/src/KSeExprUI/Editable.cpp: In member function 'virtual bool VectorEditable::parseComment(const string&)':
[  141s] /home/abuild/rpmbuild/BUILD/kseexpr-4.0.2.0/src/KSeExprUI/Editable.cpp:100:68: error: cannot bind non-const lvalue reference of type 'float_t&' {aka 'long double&'} to a value of type 'float'
[  141s]   100 |     bool parsed = KSeExpr::Utils::parseRangeComment(comment, fmin, fmax);
[  141s]       |                                                                    ^~~~
[  141s] In file included from /home/abuild/rpmbuild/BUILD/kseexpr-4.0.2.0/src/KSeExprUI/Editable.cpp:17:
[  141s] /home/abuild/rpmbuild/BUILD/kseexpr-4.0.2.0/src/KSeExprUI/Utils.h:14:82: note:   initializing argument 3 of 'bool KSeExpr::Utils::parseRangeComment(const string&, float&, float_t&)'
[  141s]    14 |         bool parseRangeComment(const std::string &comment, float &from, float_t &to);
[  141s]       |                                                                         ~~~~~~~~~^~


The "to" parameter of KSeExpr::Utils::parseRangeComment() is still float_t...
Comment 5 Wolfgang Bauer 2021-06-29 20:26:18 UTC
I also noticed a discrepancy for the double variant between KSeExprUI/Utils.cpp and KSeExprUI/Utils.h, btw.

You changed it to bool KSeExpr::Utils::parseRangeComment(const std::string &comment, double &from, double &to) in Utils.cpp, and in Utils.h it is bool parseRangeComment(const std::string &comment, double &from, double_t &to);.

I.e. you changed it to "double &to" in Utils.cpp, but not in Utils.h where it's still "double_t &to".
Comment 6 amyspark 2021-07-01 01:29:08 UTC
Git commit 92103d30b0d469334cb10e22be26ab71033d0735 by L. E. Segovia.
Committed on 30/06/2021 at 21:30.
Pushed by lsegovia into branch 'master'.

Complete removal of float_t and double_t from function signatures

M  +3    -3    src/KSeExprUI/Utils.cpp
M  +2    -2    src/KSeExprUI/Utils.h

https://invent.kde.org/graphics/kseexpr/commit/92103d30b0d469334cb10e22be26ab71033d0735
Comment 7 Wolfgang Bauer 2021-07-01 08:34:19 UTC
I can confirm that it builds fine now on i586 too.

Thank you!