Bug 45542 - std::pow(float, int) returns double when compiled with -std=gnu++0x
Summary: std::pow(float, int) returns double when compiled with -std=gnu++0x
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-09-05 11:35 UTC by vincenzo Innocente
Modified: 2010-09-06 10:05 UTC (History)
1 user (show)

See Also:
Host:
Target: x86_64-unknown-linux-gnu
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description vincenzo Innocente 2010-09-05 11:35:05 UTC
on
Linux 2.6.18-164.11.1.el5 #1 SMP Wed Jan 20 12:36:24 CET 2010 x86_64 x86_64 x86_64 GNU/Linux
gcc version 4.6.0 20100408 (experimental) (GCC) 
and
GNU C++ (GCC) version 4.5.0 (x86_64-unknown-linux-gnu)

#include<cmath>
float sqr(float x) { return std::pow(x,2);}

produces

0000000000000020 <sqr(float)>:
  20:   0f 14 c0                unpcklps %xmm0,%xmm0
  23:   0f 5a c0                cvtps2pd %xmm0,%xmm0
  26:   f2 0f 59 c0             mulsd  %xmm0,%xmm0
  2a:   66 0f 14 c0             unpcklpd %xmm0,%xmm0
  2e:   66 0f 5a c0             cvtpd2ps %xmm0,%xmm0
  32:   c3                      retq   
  33:   66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
  39:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)

when compiled with c++ -O2 -std=gnu++0x

while c++ -O2 emits (as expected)
0000000000000020 <sqr(float)>:
  20:   f3 0f 59 c0             mulss  %xmm0,%xmm0
  24:   c3                      retq   
  25:   0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
  2a:   66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)


compilation step details
c++ -O2 -std=gnu++0x -c -v assocMath.cpp
Using built-in specs.
COLLECT_GCC=c++
COLLECT_LTO_WRAPPER=/afs/cern.ch/sw/lcg/contrib/gcc/4.5.0_20100409/x86_64-slc5-gcc43-opt/libexec/gcc/x86_64-unknown-linux-gnu/4.6.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: /build/LCG/work/gcc-4.5.0_20100409/configure --prefix=/afs/cern.ch/sw/lcg/contrib/gcc/4.5.0_20100409/x86_64-slc5-gcc43-opt --with-mpfr=/afs/cern.ch/sw/lcg/external/mpfr/2.4.2/x86_64-slc5-gcc43-opt --with-gmp=/afs/cern.ch/sw/lcg/external/gmp/4.3.2/x86_64-slc5-gcc43-opt --with-mpc=/afs/cern.ch/sw/lcg/external/mpc/0.8.1/x86_64-slc5-gcc43-opt --enable-lto --with-libelf=/afs/cern.ch/sw/lcg/external/libelf/0.8.13/x86_64-slc5-gcc43-opt --with-ppl=/afs/cern.ch/sw/lcg/external/ppl/0.10.2/x86_64-slc5-gcc43-opt --with-cloog=/afs/cern.ch/sw/lcg/external/cloog-ppl/0.15.7/x86_64-slc5-gcc43-opt --enable-languages=c,c++,fortran --disable-werror
Thread model: posix
gcc version 4.6.0 20100408 (experimental) (GCC) 
COLLECT_GCC_OPTIONS='-O2' '-std=gnu++0x' '-c' '-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /afs/cern.ch/sw/lcg/contrib/gcc/4.5.0_20100409/x86_64-slc5-gcc43-opt/libexec/gcc/x86_64-unknown-linux-gnu/4.6.0/cc1plus -quiet -v -D_GNU_SOURCE assocMath.cpp -quiet -dumpbase assocMath.cpp -mtune=generic -march=x86-64 -auxbase assocMath -O2 -std=gnu++0x -version -o /tmp/innocent/ccQs7YW8.s
GNU C++ (GCC) version 4.6.0 20100408 (experimental) (x86_64-unknown-linux-gnu)
	compiled by GNU C version 4.6.0 20100408 (experimental), GMP version 4.3.2, MPFR version 2.4.2, MPC version 0.8.1
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
ignoring nonexistent directory "/afs/cern.ch/sw/lcg/contrib/gcc/4.5.0_20100409/x86_64-slc5-gcc43-opt/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/../../../../x86_64-unknown-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /afs/cern.ch/sw/lcg/contrib/gcc/4.5.0_20100409/x86_64-slc5-gcc43-opt/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/../../../../include/c++/4.6.0
 /afs/cern.ch/sw/lcg/contrib/gcc/4.5.0_20100409/x86_64-slc5-gcc43-opt/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/../../../../include/c++/4.6.0/x86_64-unknown-linux-gnu
 /afs/cern.ch/sw/lcg/contrib/gcc/4.5.0_20100409/x86_64-slc5-gcc43-opt/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/../../../../include/c++/4.6.0/backward
 /usr/local/include
 /afs/cern.ch/sw/lcg/contrib/gcc/4.5.0_20100409/x86_64-slc5-gcc43-opt/include
 /afs/cern.ch/sw/lcg/contrib/gcc/4.5.0_20100409/x86_64-slc5-gcc43-opt/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/include
 /afs/cern.ch/sw/lcg/contrib/gcc/4.5.0_20100409/x86_64-slc5-gcc43-opt/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/include-fixed
 /usr/include
End of search list.
GNU C++ (GCC) version 4.6.0 20100408 (experimental) (x86_64-unknown-linux-gnu)
	compiled by GNU C version 4.6.0 20100408 (experimental), GMP version 4.3.2, MPFR version 2.4.2, MPC version 0.8.1
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
Compiler executable checksum: c599e68b8adba71320a274af3bca4ed6
COLLECT_GCC_OPTIONS='-O2' '-std=gnu++0x' '-c' '-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 as -V -Qy --64 -o assocMath.o /tmp/innocent/ccQs7YW8.s
GNU assembler version 2.17.50.0.6-12.el5 (x86_64-redhat-linux) using BFD version 2.17.50.0.6-12.el5 20061020
COMPILER_PATH=/afs/cern.ch/sw/lcg/contrib/gcc/4.5.0_20100409/x86_64-slc5-gcc43-opt/libexec/gcc/x86_64-unknown-linux-gnu/4.6.0/:/afs/cern.ch/sw/lcg/contrib/gcc/4.5.0_20100409/x86_64-slc5-gcc43-opt/libexec/gcc/x86_64-unknown-linux-gnu/4.6.0/:/afs/cern.ch/sw/lcg/contrib/gcc/4.5.0_20100409/x86_64-slc5-gcc43-opt/libexec/gcc/x86_64-unknown-linux-gnu/:/afs/cern.ch/sw/lcg/contrib/gcc/4.5.0_20100409/x86_64-slc5-gcc43-opt/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/:/afs/cern.ch/sw/lcg/contrib/gcc/4.5.0_20100409/x86_64-slc5-gcc43-opt/lib/gcc/x86_64-unknown-linux-gnu/
LIBRARY_PATH=/afs/cern.ch/sw/lcg/contrib/gcc/4.5.0_20100409/x86_64-slc5-gcc43-opt/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/:/afs/cern.ch/sw/lcg/contrib/gcc/4.5.0_20100409/x86_64-slc5-gcc43-opt/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/afs/cern.ch/sw/lcg/contrib/gcc/4.5.0_20100409/x86_64-slc5-gcc43-opt/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-O2' '-std=gnu++0x' '-c' '-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64'


same with
GNU C++ (GCC) version 4.5.0 (x86_64-unknown-linux-gnu)
	compiled by GNU C version 4.5.0, GMP version 4.3.2, MPFR version 2.4.2, MPC version 0.8.1

if fixed please backport to 4.5.x
Comment 1 Paolo Carlini 2010-09-05 12:42:54 UTC
There is nothing to fix here, see:

  http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#550
Comment 2 vincenzo Innocente 2010-09-05 13:09:31 UTC
Subject: Re:  std::pow(float) converts to double when compiled with -std=gnu++0x

  Ciao Paolo,
On 5 Sep, 2010, at 2:42 PM, paolo dot carlini at oracle dot com wrote:

> 
> 
> ------- Comment #1 from paolo dot carlini at oracle dot com  2010-09-05 12:42 -------
> There is nothing to fix here, see:
> 
>  http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#550
> 
> 
1) this is VERY unfortunate
 
2)
and then why
std::exp(float) invokes expf? (a well as all other transcendental and trigonometric functions that invoke xyzf)
also
std::sqrt converts to sqrtss  
?

is this not a bit inconsistent?

  vincenzo



> -- 
> 
> paolo dot carlini at oracle dot com changed:
> 
>           What    |Removed                     |Added
> ----------------------------------------------------------------------------
>             Status|UNCONFIRMED                 |RESOLVED
>         Resolution|                            |INVALID
> 
> 
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45542
> 
> ------- You are receiving this mail because: -------
> You reported the bug, or are watching the reporter.


Comment 3 Paolo Carlini 2010-09-05 15:36:47 UTC
The issue affects only mixed mode arithmetic (thus, functions taking at least two arguments), and in that case, as Howard explained, C++0x does what Fortran and C do. In any case, we are implementing correctly the FCD, for sure.
Comment 4 Paolo Carlini 2010-09-05 16:15:06 UTC
By the way, if a function taking a single argument is passed and integer, the return type is double, not float or long double and one can see that the underlying mechanism is the same. All in all, I agreed with the resolution suggested by Howard, at the time, and frankly I don't thick the DR should be re-opened. CERN should send somebody to the ISO Meetings, like Fermilab does...
Comment 5 vincenzo Innocente 2010-09-05 19:55:32 UTC
Subject: Re:  std::pow(float) converts to double when compiled with -std=gnu++0x


On 5 Sep, 2010, at 6:15 PM, paolo dot carlini at oracle dot com wrote:

> 
> 
> ------- Comment #4 from paolo dot carlini at oracle dot com  2010-09-05 16:15 -------
> By the way, if a function taking a single argument is passed and integer, the
> return type is double, not float or long double and one can see that the
> underlying mechanism is the same. All in all, I agreed with the resolution
> suggested by Howard, at the time, and frankly I don't thick the DR should be
> re-opened. CERN should send somebody to the ISO Meetings, like Fermilab does…

After reading the standard a couple of times,
I fully agree that gcc implements the standard as written including the last resolution
to remove std::(T,int) (this last bit escaped my first reading)

I've discovered that std::pow(float,float) (called for instance as std::pow(x,2.f))
behaves as "I" expect.

The fact that CERN is not represented in ISO is an old story (we are NOT affiliated to any national committee)
and we rely on Fermilab representatives.

In any case this seems to be a C99 issue and my understanding is that C++ never overrules C.

The conclusion is that we will have now to recommend to use pow(float,float) not pow(float, int)
if float behavior is desired…


          vincenzo

> 

Comment 6 Paolo Carlini 2010-09-05 23:01:11 UTC
Ok... We can discuss these issues in better detail when we met. Well, remember that this is Free Software, thus, if you are unsure about a behavior, just open the header in an editor and look inside it: isn't only allowed, is encouraged!