|
|||
|
Hi,
in C++ sqrt is supposed to be an overloaded function taking either a double,a float or a long double argument. So I would guess that an int argument should give an error message at compile time. However, I observed that my gcc 4.6.1 (Mandriva Linux 2011) compiles and runs perfectly a program such as the following : #include <iostream> #include <cmath> int main() { int a = 25; std::cout << sqrt(a) << std::endl; } How is it ? Thanks for any enlightenment. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|
||||
|
||||
|
|
|
|||
|
{ Text reformatted to fit within 72 columns. Please do it yourself. -mod }
On Tuesday, September 20, 2011 3:42:23 PM UTC+2, ptyxs wrote: > #include <iostream> > #include <cmath> > > int main() > { > int a = 25; > std::cout << sqrt(a) << std::endl; > } > > > How is it ? > Thanks for any enlightenment. Vc++ 2010 gives effectively a compiler error. The reason is not for the integer type of the argument, but for ambiguity in overload resolution. there's an implicit conversion from int to all of the three types that sqrt provides an overload. And this result in an ambiguity call! But libstdc++ (used by gcc) has this definition in math.h template<typename _Tp> __gnu_cxx::__enable_if< __is_integer< _Tp >::__value, double >::__type sin (_Tp __x) that enable sqrt for integral type resolving the ambiguity. I heven't got a copy of the standard, so I cannot say if it's required this overload. Cheers, Fulvio Esposito -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
Am 20.09.2011 15:42, schrieb ptyxs:
> Hi, > in C++ sqrt is supposed to be an overloaded function taking either a > double,a float or a long double argument. > So I would guess that an int argument should give an error message at > compile time. > However, I observed that my gcc 4.6.1 (Mandriva Linux 2011) compiles > and runs perfectly a program such as the following : > > > #include<iostream> > #include<cmath> > > int main() > { > int a = 25; > std::cout<< sqrt(a)<< std::endl; > } It is unspecified, whether this program produces a diagnostic, but for different reasons as you expect. The reason is the lack of the std:: in front of sqrt after making it available via the cmath header (see [using.linkage] p2). Once fixed this way, this program should be well-formed in C++11 based on [c.math] p11: "Moreover, there shall be additional overloads sufficient to ensure: 1. If any argument corresponding to a double parameter has type long double, then all arguments corresponding to double parameters are effectively cast to long double. 2. Otherwise, if any argument corresponding to a double parameter has type double or an integer type, then all arguments corresponding to double parameters are effectively cast to double. 3. Otherwise, all arguments corresponding to double parameters are effectively cast to float." Thus, the int argument has the same effect as calling std::sqrt(double). C99 has added similar rules in regard to the type-generic math header <tgmath.h> (see 7.25 p3). HTH & Greetings from Bremen, Daniel Krügler -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
On 21 sep, 00:10, Daniel Krügler <daniel.krueg...@googlemail.com>
wrote: > Am 20.09.2011 15:42, schrieb ptyxs: > It is unspecified, whether this program produces a diagnostic, but for > different reasons as you expect. The reason is the lack of the std:: in > front of sqrt after making it available via the cmath header (see > [using.linkage] p2). Once fixed this way, this program should be > well-formed in C++11 based on [c.math] p11: Thanks to all for the interesting answers. In fact, such a program as the following (with std:: in front of sqrt) : #include <iostream> #include <cmath> int main() { int a = 25; std::cout << std::sqrt(a) << std::endl; } doesn't compile (as expected), and outputs the following error message : [toto@localhost ~]$ g++ -std=c++0x -Wall -pedantic sqrtmy3.cpp sqrtmy3.cpp: In function ‘int main()’: sqrtmy3.cpp:8:18: error: ‘sqrt’ is not a member of ‘std’ sqrtmy3.cpp:8:18: note: suggested alternative: /usr/include/bits/mathcalls.h:157:1: note: ‘sqrt’ -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
On 2011-09-21 00:09, Fulvio Esposito wrote:
> On Tuesday, September 20, 2011 3:42:23 PM UTC+2, ptyxs wrote: >> #include<iostream> >> #include<cmath> >> >> int main() >> { >> int a = 25; >> std::cout<< sqrt(a)<< std::endl; >> } >> >> >> How is it ? >> Thanks for any enlightenment. > > Vc++ 2010 gives effectively a compiler error. The reason is not for the > integer type of the argument, but for ambiguity in overload resolution. > there's an implicit conversion from int to all of the three types that > sqrt provides an overload. And this result in an ambiguity call! This result would be expected for a C++03-conforming compiler, but not for a C++11-conforming one. > But libstdc++ (used by gcc) has this definition in math.h > > template<typename _Tp> __gnu_cxx::__enable_if< __is_integer< > _Tp>::__value, double >> ::__type sin (_Tp __x) > > that enable sqrt for integral type resolving the ambiguity. I heven't got > a copy of the standard, so I cannot say if it's required this overload. In C++11 the example code is supposed to be well-formed, it is required by [c.math] p11 which says that integer arguments shall behave as if they would be provided as double values. HTH & Greetings from Bremen, Daniel Krügler -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
On 2011-09-21 15:29, ptyxs wrote:
> On 21 sep, 00:10, Daniel Krügler<daniel.krueg...@googlemail.com> > wrote: >> Am 20.09.2011 15:42, schrieb ptyxs: >> It is unspecified, whether this program produces a diagnostic, but for >> different reasons as you expect. The reason is the lack of the std:: in >> front of sqrt after making it available via the cmath header (see >> [using.linkage] p2). Once fixed this way, this program should be >> well-formed in C++11 based on [c.math] p11: > > Thanks to all for the interesting answers. > > In fact, such a program as the following (with std:: in front of > sqrt) : > > > #include<iostream> > #include<cmath> > > > int main() > { > int a = 25; > std::cout<< std::sqrt(a)<< std::endl; > } > > > doesn't compile (as expected), and outputs the following error > message : Why do you say that this failure is expected? It is not. > [toto@localhost ~]$ g++ -std=c++0x -Wall -pedantic sqrtmy3.cpp > sqrtmy3.cpp: In function ‘int main()’: > sqrtmy3.cpp:8:18: error: ‘sqrt’ is not a member of ‘std’ > sqrtmy3.cpp:8:18: note: suggested alternative: > /usr/include/bits/mathcalls.h:157:1: note: ‘sqrt’ This must be a defect in the library implementation, because it violates [headers] p5: "In the C++ standard library, however, the declarations (except for names which are defined as macros in C) are within namespace scope (3.3.6) of the namespace std. It is unspecified whether these names are first declared within the global namespace scope and are then injected into namespace std by explicit using-declarations (7.3.3)." But sqrt is no macro in the C library, therefore std::sqrt must be available when including <cmath>. HTH & Greetings from Bremen, Daniel Krügler -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
ptyxs <kerloch@gmail.com> writes:
> #include <iostream> > #include <cmath> > > int main() > { > int a = 25; > std::cout << std::sqrt(a) << std::endl; > } > > doesn't compile (as expected), and outputs the following error > message : > > [toto@localhost ~]$ g++ -std=c++0x -Wall -pedantic sqrtmy3.cpp > sqrtmy3.cpp: In function ‘int main()’: > sqrtmy3.cpp:8:18: error: ‘sqrt’ is not a member of ‘std’ > sqrtmy3.cpp:8:18: note: suggested alternative: > /usr/include/bits/mathcalls.h:157:1: note: ‘sqrt’ You should say what version of g++ you have -- the above compiles without error or warning with g++ versions 4.4 - 4.7, and with the clang++ trunk version... (the most recent release version of clang++ doesn't support c++0x well enough). -Miles -- Future, n. That period of time in which our affairs prosper, our friends are true and our happiness is assured. [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
On Sep 22, 9:46 pm, Miles Bader <mi...@gnu.org> wrote:
> You should say what version of g++ you have I said it in my first post. Have a look at it... -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
On Wed, 21 Sep 2011 06:29:39 -0700 (PDT), ptyxs <kerloch@gmail.com> wrote:
> > Thanks to all for the interesting answers. > In fact, such a program as the following (with std:: in front of > sqrt) : > > int a = 25; > std::cout << std::sqrt(a) << std::endl; > > doesn't compile (as expected), and outputs the following error > message : > > [toto@localhost ~]$ g++ -std=c++0x -Wall -pedantic sqrtmy3.cpp > sqrtmy3.cpp: In function ‘int main()’: > sqrtmy3.cpp:8:18: error: ‘sqrt’ is not a member of ‘std’ > sqrtmy3.cpp:8:18: note: suggested alternative: > /usr/include/bits/mathcalls.h:157:1: note: ‘sqrt’ I'd say that your compiler or more likely standard headers are wrong. For what it's worth I get CC -o main x.cpp -library=stlport4 "x.cpp", line 8: Error: Overloading ambiguity between "std::sqrt(double)" and "std::sqrt(long double)". 1 Error(s) detected. with Oracle Studio 12.3 beta. A+ Paul -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
ptyxs <kerloch@gmail.com> writes:
>> You should say what version of g++ you have > > I said it in my first post. Have a look at it... I see ("4.6.1; Mandriva Linux 2011"). It looks, then, like the g++ installation on your machine may simply be broken. [As I mentioned before, your example / command work fine with g++ on Debian, with g++ 4.4 - 4.7, and clang++-trunk.] -Miles -- Non-combatant, n. A dead Quaker. [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
On Sep 24, 1:40 am, Miles Bader <mi...@gnu.org> wrote:
> ptyxs <kerl...@gmail.com> writes: > >> You should say what version of g++ you have > > > I said it in my first post. Have a look at it... > > I see ("4.6.1; Mandriva Linux 2011"). > > It looks, then, like the g++ installation on your machine may simply > be broken. > > [As I mentioned before, your example / command work fine with g++ on > Debian, with g++ 4.4 - 4.7, and clang++-trunk.] > > -Miles { quoted signature and banner removed by mod -- please do it yourself. -mod } I tried the same programs (with and without 'std::' in front of sqrt) on g++ 4.5.2 on a completely different installation (Ubuntu 10.04) and I noticed exactly the same behaviors as with 4.6.1 on Mandriva 2011. (btw gcc 4.7.0 is described as 'in development' on the official page of gcc). -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
ptyxs <kerloch@gmail.com> writes:
> On Sep 24, 1:40 am, Miles Bader <mi...@gnu.org> wrote: >> It looks, then, like the g++ installation on your machine may simply >> be broken. >> >> [As I mentioned before, your example / command work fine with g++ on >> Debian, with g++ 4.4 - 4.7, and clang++-trunk.] > > I tried the same programs (with and without 'std::' in front of sqrt) > on g++ 4.5.2 on a completely different installation (Ubuntu 10.04) and > I noticed exactly the same behaviors as with 4.6.1 on Mandriva 2011. Then presumably ubuntu 10.04 is broken in the same way -- it may be an upstream bug that has been fixed since (ubuntu 10.04 is somewhat old). The Debian versions I tried (none of which exhibit your problem): g++-4.4 (Debian 4.4.6-11) 4.4.6 g++-4.5 (Debian 4.5.3-9) 4.5.3 g++-4.6 (Debian 4.6.1-11) 4.6.1 g++ (Debian 20110914-1) 4.7.0 20110914 (experimental) [trunk revision 178863] These probably all have fixes applied from the upstream maintenance branch that are weren't in the original release. > (btw gcc 4.7.0 is described as 'in development' on the official page > of gcc). Yes, it's the development trunk. Can't hurt to try that too though... :] Maybe you could get a more informed answer by sending a message to gcc-help@gcc.gnu.org ? -Miles -- Suburbia: where they tear out the trees and then name streets after them. [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
On Sep 26, 2:19 am, Miles Bader <mi...@gnu.org> wrote:
> Then presumably ubuntu 10.04 is broken in the same way -- it may be an > upstream bug that has been fixed since (ubuntu 10.04 is somewhat old). > Sorry, it was a typo, I tried it on a Ubuntu 11.04 (not 10.04). -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
It seems I made some mistake.
To clarify, here are my observations : First program with 'std::' in front of sqrt : #include <iostream> // #include <cmath> // OK Ubuntu 11.04 (gcc 4.5.2) & Mandriva 2011 (gcc 4.6.1) #include <math.h> // errror with Ubuntu 11.04 (gcc 4.5.2) & Mandriva 2011 (gcc 4.6.1) int main() { int a = 25; std::cout << std::sqrt(a) << std::endl; } Second program, without 'std::' in front of sqrt : #include <iostream> #include <cmath> // OK Ubuntu 11.04 (gcc 4.5.2) & Mandriva 2011 (gcc 4.6.1) // #include <math.h> // OK with Ubuntu 11.04 (gcc 4.5.2) & Mandriva 2011 (gcc 4.6.1) int main() { int a = 25; std::cout << sqrt(a) << std::endl; } -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
Am 29.09.2011 20:01, schrieb ptyxs:
> It seems I made some mistake. > To clarify, here are my observations : > > First program with 'std::' in front of sqrt : > > #include<iostream> > // #include<cmath> // OK Ubuntu 11.04 (gcc 4.5.2)& Mandriva 2011 > (gcc 4.6.1) > #include<math.h> // errror with Ubuntu 11.04 (gcc 4.5.2)& Mandriva > 2011 (gcc 4.6.1) > > int main() > { > int a = 25; > std::cout<< std::sqrt(a)<< std::endl; > } This is conforming behaviour. The components from header <math.h> are guaranteed to be available in the global namespace and the components from header <cmath> are guaranteed to be available from namespace std (This rule applies to all headers <x.h> from the C library and their counterpart <cx>). *Either* of these headers *may* provide these names from namespace std or from the global namespace, respectively. > Second program, without 'std::' in front of sqrt : > > > #include<iostream> > #include<cmath> // OK Ubuntu 11.04 (gcc 4.5.2)& Mandriva 2011 (gcc > 4.6.1) > // #include<math.h> // OK with Ubuntu 11.04 (gcc 4.5.2)& Mandriva > 2011 (gcc 4.6.1) > > int main() > { > int a = 25; > std::cout<< sqrt(a)<< std::endl; > } Again, both are conforming, see above for the reason. It makes therefore a lot of difference when discussing about header <x.h> or header cx>! HTH & Greetings from Bremen, Daniel Krügler -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|