7

while doing some homework in my very strange C++ book, which I've been told before to throw away, had a very peculiar code segment. I know homework stuff always throws in extra "mystery" to try to confuse you like indenting 2 lines after a single-statement for-loop. But this one I'm confused on because it seems to serve some real-purpose.

basically it is like this:

int counter=10;
...
if(pow(floor(sqrt(counter+0.0)),2) == counter)
...

I'm interested in this part especially:

sqrt(counter+0.0)

Is there some purpose to the +0.0? Is this the poormans way of doing a static cast to a double? Does this avoid some compiler warning on some compiler I do not use? The entire program printed the exact same thing and compiled without warnings on g++ whenever I left out the +0.0 part. Maybe I'm not using a weird enough compiler?

Edit:

Also, does gcc just break standard and not make an error for Ambiguous reference since sqrt can take 3 different types of parameters?

[earlz@EarlzBeta-~/projects/homework1] $ cat calc.cpp
#include <cmath>

int main(){
  int counter=0;
  sqrt(counter);
}
[earlz@EarlzBeta-~/projects/homework1] $ g++ calc.cpp
/usr/lib/libstdc++.so.47.0: warning: strcpy() is almost always misused, please use strlcpy()
/usr/lib/libstdc++.so.47.0: warning: strcat() is almost always misused, please use strlcat()
[earlz@EarlzBeta-~/projects/homework1] $

Also, here is the relevant part of my system libraries cmath I'm not too keen on templates, so I'm not sure what it's doing

  using ::sqrt;

  inline float
  sqrt(float __x)
  { return __builtin_sqrtf(__x); }

  inline long double
  sqrt(long double __x)
  { return __builtin_sqrtl(__x); }

  template<typename _Tp>
    inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
                       double>::__type
    sqrt(_Tp __x)
    { return __builtin_sqrt(__x);
Community
  • 1
  • 1
Earlz
  • 62,085
  • 98
  • 303
  • 499

3 Answers3

13

Is this the poormans way of doing a static cast to a double?

Yes.

You can't call sqrt with an int as its parameter, because sqrt takes a float, double, or long double. You have to cast the int to one of those types, otherwise the call is ambiguous.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • 1
    but why? it's not even necessary in this case. – Earlz Apr 12 '10 at 04:03
  • 5
    @Earlz: I don't know why anyone would recommend using `+ 0.0`. The only thing it has going for it is that it's less to type than `static_cast` or `(double)`, but that's not a good reason to use it. – James McNellis Apr 12 '10 at 04:08
  • @James why does g++ not give an error or warning about this then? See my edit. – Earlz Apr 12 '10 at 04:10
  • 1
    @James, yeah, but even an explicit cast isn't necessary. Implicit conversion should take care of it. – Derrick Turk Apr 12 '10 at 04:11
  • For your guys information this is actually a way most book writers teach to cast a int into a double. As Precision Math added to Interger Math defaults to Precision. – AjayP Apr 12 '10 at 04:13
  • Also what the book is looking out for is if you modify the code to make counter taken from user input it would automatically cast it. – AjayP Apr 12 '10 at 04:14
  • The reason you don't get a warning is because the compiler is satisfied. It wants a double and it gets a double. The difference between adding 0.0 and explicitly casting using the C++ `static_cast` operator is that the latter approach is very explicit. No one would ask "what are you doing" in that case (as opposed to adding 0.0, which is herein demonstratedly unclear). – wilhelmtell Apr 12 '10 at 04:16
  • 1
    Data points: Without a cast of some sort (or forcing the expression to be of type double) MSVC 2003 or later and Comeau generate an error; GCC 3.4.5, Digital Mars and MSVC 6 do not. I wonder how the later decide to resolve the overload? – Michael Burr Apr 12 '10 at 04:16
  • @Earlz: I don't know why g++ accepts your trivial example, unless you don't have the additional overloads for `float` and `long double` in your standard library. Visual C++ and Comeau both rightly reject the example code due to the overload ambiguity. – James McNellis Apr 12 '10 at 04:17
  • @Michael. Ah, I compile all my homework code with g++, so guess this is why I didn't catch it. So apparently this guy couldn't write `static_cast(counter)` and instead had to leave code to the student to figure out... which he never talked about this trick specifically in the book. – Earlz Apr 12 '10 at 04:19
  • @James, well the overloaded ones must not be part of the ANSI standard (and therefore, not included in the "standard libraries") cause with the most up to date gcc, it compiles fine without warnings. – Earlz Apr 12 '10 at 04:20
  • 1
    @Earlz: The overloads are all part of the C++ standard library and have been since the language was standardized. In the C standard library they have different names (since they have to): `sqrtf`, `sqrt`, and `sqrtl`. You can find out pretty easily by looking in your `cmath` header. – James McNellis Apr 12 '10 at 04:22
  • 1
    @Michael Burr: In the standard library that came with VC 6 the overloaded versions of `sqrt` (and other C-style math functions) are disabled by defualt by a macro. I don't remember the name of the macro, but in any case this is why VC 6 does not complain. In VC 6 by default `sqrt` works the same way it worked in C - it expects `double` and only `double`. No overloads. – AnT stands with Russia Apr 12 '10 at 04:30
  • @James, so did gcc violate the standard then? See my edit for my cmath file. – Earlz Apr 12 '10 at 04:37
  • 1
    @Earlz: It explains why there is no overload ambiguity. The function template is used to select the `sqrt(double)` overload if the argument is of an integer type. I don't think that _violates_ the library standard (it _might_, but I doubt it). It's certainly an implementation-specific addition though, and relying on it would be a bad idea if you are trying to write portable code. – James McNellis Apr 12 '10 at 04:47
  • @James. ok, good to know. I Guess that's what I get for only using g++ and glibc :P – Earlz Apr 12 '10 at 04:55
  • Personally, I think that this + 0.0 business is crazy. I thought everybody knew that you should multiply by 1.0 in a situation like this. – Michael Daum Apr 12 '10 at 06:56
  • @Michael. what? I was always under the impression to just suck it up and do a static_typecast or at least a C-style cast. – Earlz Apr 12 '10 at 13:52
0

the reason for the expression counter + 0.0 is to explicitly make it a real number. if we donot add 0.0 the compiler will do implicit conversion

0

It's just another way to cast to a double. This is because sqrt doesn't accept ints. Because a double is higher it will merge the int into the 0.0. The same way can be done for converting from (int,double,float) to string.

double n = 0;

string m = ""+n;

flopex
  • 434
  • 3
  • 6
  • 11