complex problem

35 views
Skip to first unread message

nunya biznez

unread,
Jul 9, 2014, 11:08:09 PM7/9/14
to emscripte...@googlegroups.com
I'm trying to compile some c++ code and I have some issues with using the complex library.
The code does some funny pointer stuff with the complex class like this:

    COMPLEX x;
    COMPLEX* px = &x;
    double* prx = &x.real();
    double* pix = &x.imag();
    assert(reinterpret_cast<void*>(prx) == reinterpret_cast<void*>(px));
    assert(reinterpret_cast<void*>(pix-1) == reinterpret_cast<void*>(px));

and this:

    tr_load_point(_n[ii], _n[jj], &(_matrix[nii][njj].real()), &(_matrix[nii][njj].imag()));

The error I get is cannot take the address of an rvalue of type 'double'.

I get the same errors when I use clang by itself with "-std=c++11 " ,but it compiles fine without that setting.
Same thing with gcc.

I was hoping a compiler setting for emscripten would solve the problem.

Thanks.

Jukka Jylänki

unread,
Jul 10, 2014, 4:16:56 AM7/10/14
to emscripte...@googlegroups.com
You could try building with -std=c++03 to test if that solves the problem.

I am assuming that the code is something like this:

double COMPLEX::real() const { return this->real_value; }
double COMPLEX::imag() const { return this->imag_value; }

in which case the two assert()s you have are broken assumptions, in both emscripten and native: the assert()s won't hold if you take the address of a temporary, they'll be pointing to something else. If you change your code to something like

const double &COMPLEX::real() const { return this->real_value; }
const double &COMPLEX::imag() const { return this->imag_value; }
double &COMPLEX::real() { return this->real_value; }
double &COMPLEX::imag() { return this->imag_value; }

or

    COMPLEX x;
    COMPLEX* px = &x;
    double* prx = &x.real_value;
    double* pix = &x.imag_value;

    assert(reinterpret_cast<void*>(prx) == reinterpret_cast<void*>(px));
    assert(reinterpret_cast<void*>(pix-1) == reinterpret_cast<void*>(px));

then that should fix the code up. The first form returns by reference rather than by value, and the second form directly takes in addresses of the actual COMPLEX member vars proper, and not some temporaries.


--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

wikitronic

unread,
Jul 10, 2014, 9:59:37 AM7/10/14
to emscripte...@googlegroups.com
Thanks for your reply.

 -std=c++98 or -std=c++03 doesn't help.
 
There is also one more line of code with an error, something like:

complex.real()=0;

I'm not sure what that does. It looks like it just sets the real value to 0.

I have this short test code:

#include <iostream>
#include <complex>

using namespace std;


int main(int argc, const char *argv[]){
complex<double> x;
x.real(1);
cout<<x.real()<<'\n'; 

x.real()=0;
cout<<x.real()<<'\n';


x.real(2);
cout<<x.real()<<'\n';


double* y=&x.real();
cout<<*y<<'\n';
}

It has the same problem as the source code I'm trying to build.
 
I could try the changes you proposed but the member variables are private so I would have to modify the library file.

Here is the declaration in the library file:


template<>
class _LIBCPP_TYPE_VIS_ONLY complex<double>
{
    double __re_;
    double __im_;
public:
    typedef double value_type;

    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(double __re = 0.0, double __im = 0.0)
        : __re_(__re), __im_(__im) {}
    _LIBCPP_CONSTEXPR complex(const complex<float>& __c);
    explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c);

    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double real() const {return __re_;}
    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double imag() const {return __im_;}

    _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
    _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}

    _LIBCPP_INLINE_VISIBILITY complex& operator= (double __re)
        {__re_ = __re; __im_ = value_type(); return *this;}
    _LIBCPP_INLINE_VISIBILITY complex& operator+=(double __re) {__re_ += __re; return *this;}
    _LIBCPP_INLINE_VISIBILITY complex& operator-=(double __re) {__re_ -= __re; return *this;}
    _LIBCPP_INLINE_VISIBILITY complex& operator*=(double __re) {__re_ *= __re; __im_ *= __re; return *this;}
    _LIBCPP_INLINE_VISIBILITY complex& operator/=(double __re) {__re_ /= __re; __im_ /= __re; return *this;}

    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
        {
            __re_ = __c.real();
            __im_ = __c.imag();
            return *this;
        }
    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
        {
            __re_ += __c.real();
            __im_ += __c.imag();
            return *this;
        }
    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
        {
            __re_ -= __c.real();
            __im_ -= __c.imag();
            return *this;
        }
    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
        {
            *this = *this * complex(__c.real(), __c.imag());
            return *this;
        }
    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
        {
            *this = *this / complex(__c.real(), __c.imag());
            return *this;
        }
};
 

It apears to be the same library file from llvm. I'm using the fastcomp compiler. So if there is no other solution I will go ahead and try to modify the library file source and then build the project.






--
You received this message because you are subscribed to a topic in the Google Groups "emscripten-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/emscripten-discuss/OnzpRJAxzO0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to emscripten-disc...@googlegroups.com.

wikitronic

unread,
Jul 10, 2014, 7:30:26 PM7/10/14
to emscripte...@googlegroups.com
I modified the complex library file to make the variables public and made the changes you suggested. It seems to work perfectly.

Thanks.

Reply all
Reply to author
Forward
0 new messages