GCC/MSVC++ difference

Discussion in 'C++' started by bleyddyn.apRhys@gmail.com, Mar 12, 2007.

  1. Guest

    I have a bit of code that doesn't compile under MSVC++ but does under
    GCC. Even under GCC, though, it seems odd that I don't need a std
    namespace qualifier for the exp function.

    Is this just one of those difference I have to #ifdef around, or is
    there a bit of code that will compile under both?

    Basically, I have a std::vector<double>. I want to replace each item
    in the vector with the exp() of that item. The code does work, and
    there's a simple work-around under Window's, but I'd prefer to
    understand why it doesn't compile.

    Below is the code and the VC++ error message. The workaround is to
    replace exp with locExp in the call to transform.

    Thanks for any suggestions!
    Andrew


    Version info:
    Visual Studio 2005, Academic Edition, Version 8.0.50727.42
    Visual C++ 2005 77633-233-0020534-41001

    g++: powerpc-apple-darwin8-g++-4.0.1


    Compiling...
    transform.cpp
    c:\documents and settings\asalamon\my documents\test
    \transform.cpp(45) : error C2780: '_OutIt
    std::transform(_InIt1,_InIt1,_InIt2,_OutIt,_Fn2)' : expects 5
    arguments - 4 provided
    c:\program files\microsoft visual studio 8\vc\include
    \algorithm(797) : see declaration of 'std::transform'
    c:\documents and settings\asalamon\my documents\test
    \transform.cpp(45) : error C2914: 'std::transform' : cannot deduce
    template argument as function argument is ambiguous
    c:\documents and settings\asalamon\my documents\test
    \transform.cpp(45) : error C2784: '_OutIt
    std::transform(_InIt,_InIt,_OutIt,_Fn1)' : could not deduce template
    argument for '_OutIt' from 'std::_Vector_iterator<_Ty,_Alloc>'
    with
    [
    _Ty=double,
    _Alloc=std::allocator<double>
    ]
    c:\program files\microsoft visual studio 8\vc\include
    \algorithm(682) : see declaration of 'std::transform'
    Build log was saved at "file://c:\Documents and Settings\asalamon\My
    Documents\Test\testTransform\testTransform\Debug\BuildLog.htm"
    testTransform - 3 error(s), 0 warning(s)


    // Begin code
    #include <iomanip>
    #include <vector>
    #include <algorithm>
    #include <iostream>
    #include <cmath> // for exp()

    void testTransformExp();

    int main()
    {
    testTransformExp();
    }

    void printVec( std::vector<double> &vec )
    {
    for( unsigned int i = 0; i < vec.size(); ++i )
    std::cout << vec << ", ";
    std::cout << std::endl;
    }

    inline double locExp( double val )
    {
    return exp(val);
    }

    void testTransformExp()
    {
    std::vector<double> res( 8, 0.0 );

    res[0] = 1.0;
    res[1] = 2.0;
    res[2] = 10.0;
    res[3] = 30.0;
    res[4] = 100.0;
    res[5] = 400.0;
    res[6] = 1000.0;
    res[7] = 5000.0;

    std::transform( res.begin(), res.end(), res.begin(), exp ); //
    calculate the exponent of each element
    printVec( res );
    }
     
    , Mar 12, 2007
    #1
    1. Advertising

  2. Ian Collins Guest

    wrote:
    > I have a bit of code that doesn't compile under MSVC++ but does under
    > GCC. Even under GCC, though, it seems odd that I don't need a std
    > namespace qualifier for the exp function.
    >
    > std::transform( res.begin(), res.end(), res.begin(), exp );
    > printVec( res );
    > }
    >

    exp, having extern "C" linkage, probably doesn't match std::transform's
    UnaryOperation template parameter.

    --
    Ian Collins.
     
    Ian Collins, Mar 12, 2007
    #2
    1. Advertising

  3. P.J. Plauger Guest

    <> wrote in message
    news:...

    >I have a bit of code that doesn't compile under MSVC++ but does under
    > GCC. Even under GCC, though, it seems odd that I don't need a std
    > namespace qualifier for the exp function.
    >
    > Is this just one of those difference I have to #ifdef around, or is
    > there a bit of code that will compile under both?
    >
    > Basically, I have a std::vector<double>. I want to replace each item
    > in the vector with the exp() of that item. The code does work, and
    > there's a simple work-around under Window's, but I'd prefer to
    > understand why it doesn't compile.
    >
    > Below is the code and the VC++ error message. The workaround is to
    > replace exp with locExp in the call to transform.


    Right. The problem you face is that VC++ conforms better to the C++
    Standard than does GCC. The former provides the required overloads
    for exp; the latter is at the mercy of the underlying C library to
    provide those overloads, and certainly glibc fails to do so. By
    interposing the wrapper function, you disambiguate the call to
    transform.

    HTH,

    P.J. Plauger
    Dinkumware, Ltd.
    http://www.dinkumware.com
     
    P.J. Plauger, Mar 12, 2007
    #3
  4. Guest

    On Mar 12, 2:26 pm, "P.J. Plauger" <> wrote:
    >
    > Right. The problem you face is that VC++ conforms better to the C++
    > Standard than does GCC. The former provides the required overloads
    > for exp; the latter is at the mercy of the underlying C library to
    > provide those overloads, and certainly glibc fails to do so. By
    > interposing the wrapper function, you disambiguate the call to
    > transform.
    >
    > HTH,
    >
    > P.J. Plauger
    > Dinkumware, Ltd.http://www.dinkumware.com


    I'm not sure if it helps my understanding much, but thanks! Looking
    through the cmath header file, it certainly seems like there are
    overloads for exp, but that's why I didn't understand why I don't need
    a std:: qualifier for exp. Maybe the __enable_if... macro prevents any
    re-definition of exp?

    <snipped from parts of cmath>
    #undef exp
    ....
    namespace std
    {
    using ::exp;

    inline float
    exp(float __x)
    { return __builtin_expf(__x); }

    inline long double
    exp(long double __x)
    { return __builtin_expl(__x); }

    template<typename _Tp>
    inline typename __enable_if<double,
    __is_integer<_Tp>::__value>::__type
    exp(_Tp __x)
    { return __builtin_exp(__x); }
    }

    I did come up with what seems like a cleaner way to fix it, though:

    typedef double (*expType) (double);
    std::transform( res.begin(), res.end(), res.begin(),
    static_cast<expType>(exp) );

    It builds and runs properly under both compilers. I guess I'll just
    leave it at that for now, since it does seem to work.

    Thanks!
    Andrew
     
    , Mar 12, 2007
    #4
  5. In article <>,
    wrote:

    > On Mar 12, 2:26 pm, "P.J. Plauger" <> wrote:
    > >
    > > Right. The problem you face is that VC++ conforms better to the C++
    > > Standard than does GCC. The former provides the required overloads
    > > for exp; the latter is at the mercy of the underlying C library to
    > > provide those overloads, and certainly glibc fails to do so. By
    > > interposing the wrapper function, you disambiguate the call to
    > > transform.
    > >
    > > HTH,
    > >
    > > P.J. Plauger
    > > Dinkumware, Ltd.http://www.dinkumware.com

    >
    > I'm not sure if it helps my understanding much, but thanks! Looking
    > through the cmath header file, it certainly seems like there are
    > overloads for exp, but that's why I didn't understand why I don't need
    > a std:: qualifier for exp. Maybe the __enable_if... macro prevents any
    > re-definition of exp?
    >
    > <snipped from parts of cmath>
    > #undef exp
    > ...
    > namespace std
    > {
    > using ::exp;
    >
    > inline float
    > exp(float __x)
    > { return __builtin_expf(__x); }
    >
    > inline long double
    > exp(long double __x)
    > { return __builtin_expl(__x); }
    >
    > template<typename _Tp>
    > inline typename __enable_if<double,
    > __is_integer<_Tp>::__value>::__type
    > exp(_Tp __x)
    > { return __builtin_exp(__x); }
    > }
    >
    > I did come up with what seems like a cleaner way to fix it, though:
    >
    > typedef double (*expType) (double);
    > std::transform( res.begin(), res.end(), res.begin(),
    > static_cast<expType>(exp) );
    >
    > It builds and runs properly under both compilers. I guess I'll just
    > leave it at that for now, since it does seem to work.


    What happens if you use std::exp instead of exp. Technically that is
    all that should be exposed by <cmath> today.

    -Howard
     
    Howard Hinnant, Mar 12, 2007
    #5
  6. Guest

    On Mar 12, 3:55 pm, Howard Hinnant <> wrote:
    > In article <>,
    >
    > What happens if you use std::exp instead of exp. Technically that is
    > all that should be exposed by <cmath> today.
    >
    > -Howard


    With this line:
    std::transform( res.begin(), res.end(), res.begin(), std::exp );

    For gcc:
    transform.cpp: In function 'void testTransformExp()':
    transform.cpp:46: error: no matching function for call to
    'transform(__gnu_cxx::__normal_iterator<double*, std::vector<double,
    std::allocator<double> > >, __gnu_cxx::__normal_iterator<double*,
    std::vector<double, std::allocator<double> > >,
    __gnu_cxx::__normal_iterator<double*, std::vector<double,
    std::allocator<double> > >, <unknown type>)'

    And a similar error from VC++ (sorry, can't copy/paste from Windows):
    error C2780 ... expects 5 arguments - 4 provided
    .... can't deduce template argument as function argument is ambiguous
    ....
     
    , Mar 12, 2007
    #6
  7. Kai-Uwe Bux Guest

    wrote:

    > I have a bit of code that doesn't compile under MSVC++ but does under
    > GCC. Even under GCC, though, it seems odd that I don't need a std
    > namespace qualifier for the exp function.
    >
    > Is this just one of those difference I have to #ifdef around, or is
    > there a bit of code that will compile under both?
    >
    > Basically, I have a std::vector<double>. I want to replace each item
    > in the vector with the exp() of that item. The code does work, and
    > there's a simple work-around under Window's, but I'd prefer to
    > understand why it doesn't compile.
    >
    > Below is the code and the VC++ error message. The workaround is to
    > replace exp with locExp in the call to transform.
    >
    > Thanks for any suggestions!
    > Andrew
    >

    [snip]
    > // Begin code
    > #include <iomanip>
    > #include <vector>
    > #include <algorithm>
    > #include <iostream>
    > #include <cmath> // for exp()
    >
    > void testTransformExp();
    >
    > int main()
    > {
    > testTransformExp();
    > }
    >
    > void printVec( std::vector<double> &vec )
    > {
    > for( unsigned int i = 0; i < vec.size(); ++i )
    > std::cout << vec << ", ";
    > std::cout << std::endl;
    > }
    >
    > inline double locExp( double val )
    > {
    > return exp(val);
    > }
    >
    > void testTransformExp()
    > {
    > std::vector<double> res( 8, 0.0 );
    >
    > res[0] = 1.0;
    > res[1] = 2.0;
    > res[2] = 10.0;
    > res[3] = 30.0;
    > res[4] = 100.0;
    > res[5] = 400.0;
    > res[6] = 1000.0;
    > res[7] = 5000.0;
    >
    > std::transform( res.begin(), res.end(), res.begin(), exp );


    I think, the compiler needs some help to chose the right overload for
    std::exp:

    std::transform( res.begin(), res.end(), res.begin(),
    static_cast< double(*)(double)> ( std::exp ) );

    [snip]
    > printVec( res );
    > }



    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Mar 13, 2007
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?ISO-8859-1?Q?Christian_Engstr=F6m?=

    base/derived ambiguity with gcc, but not with MSVC

    =?ISO-8859-1?Q?Christian_Engstr=F6m?=, Feb 11, 2004, in forum: C++
    Replies:
    2
    Views:
    375
    =?ISO-8859-1?Q?Christian_Engstr=F6m?=
    Feb 12, 2004
  2. =?ISO-8859-1?Q?Christian_Engstr=F6m?=

    Another base/derived problem with gcc, but not with MSVC

    =?ISO-8859-1?Q?Christian_Engstr=F6m?=, Feb 12, 2004, in forum: C++
    Replies:
    7
    Views:
    373
    John Harrison
    Feb 13, 2004
  3. Derek
    Replies:
    10
    Views:
    616
    tom_usenet
    Jul 19, 2004
  4. Thomas Casanova

    template from MSVC++ to Linux gcc 3.3.4

    Thomas Casanova, Nov 9, 2004, in forum: C++
    Replies:
    3
    Views:
    467
    Andre Dajd
    Nov 9, 2004
  5. Reetesh Mukul
    Replies:
    3
    Views:
    1,049
    Greg Herlihy
    Aug 6, 2009
Loading...

Share This Page