2

d is a double type data and p is a pointer to it. When both of them are separately casted to int explicitly, it gives the following error for pointer p's cast. : cast from double* to int loses precision

#include<iostream>
using namespace std;
int main()
{
    int i,j;
    double d=3.5;
    double* p=&d;
    i=(int)d;
    j=(int)p;   // this line gives the error
    cout<<i<<" "<<j;
    return 0;
}

I expected the error there to be "invalid conversion from double* to int. Why is it not so?

Also, why didn't the cast for data d give the "loses precision" error if it does so for the pointer p?

Oblivion
  • 7,176
  • 2
  • 14
  • 33
M. Krishna
  • 21
  • 1
  • 2

3 Answers3

2

I expected the error there to be "invalid conversion from 'double*' to 'int'". Why is it not so?

I assume it's just a compiler-dependent way of dealing with this error. On clang I get something similar, maybe more informative:

error: cast from pointer to smaller type 'int' loses information

Also, why didn't the cast for data d give the "loses precision" error if it does so for the pointer p?

Conversion from a float or double to an int is among standard conversions, not erroneous and sometimes useful. This should not throw an error, more on it here,

A prvalue of floating-point type can be converted to a prvalue of any integer type. The fractional part is truncated, that is, the fractional part is discarded. If the value cannot fit into the destination type, the behavior is undefined (even when the destination type is unsigned, modulo arithmetic does not apply). If the destination type is bool, this is a boolean conversion (see below).

A prvalue of integer or unscoped enumeration type can be converted to a prvalue of any floating-point type. If the value cannot be represented correctly, it is implementation defined whether the closest higher or the closest lower representable value will be selected, although if IEEE arithmetic is supported, rounding defaults to nearest. If the value cannot fit into the destination type, the behavior is undefined. If the source type is bool, the value false is converted to zero, and the value true is converted to one.

Community
  • 1
  • 1
atru
  • 4,699
  • 2
  • 18
  • 19
0

int is not guaranteed to be able to hold the value of a pointer. In your case I believe intptr_t would work.

MrPromethee
  • 721
  • 9
  • 18
-1

You lose precision, it's fairly self explanatory.

In this case there's 2 reasons why you do.

  1. An integer only has 4 bytes, whereas a double has 8, meaning you can't put the entire double into the integer. (In reality it's implementation defined)
  2. A double has decimal numbers, an integer does not, so an integer simply cannot hold information about decimal numbers.

The reason that line errors is because you're trying to cast a pointer to an integer, which is not possible, what you meant to do is j = (int)*p;

There's several bad practices in your code.

  1. using namespace std; Why is "using namespace std;" considered bad practice?

https://isocpp.org/wiki/faq/coding-standards#using-namespace-std

How to use an iterator? (example of it causing problems)

Confusion about pointers and references in C++ (another example of it causing problems; using std::swap; would cause the same exact problem as well)

  1. C style casts This is (type), in your case specifically (int) There are 2 main casts that should be used in C++, static_cast and reinterpret_cast. (There are 2 more types, const_cast and dynamic_cast, but these are irrelevant in this case, and const_cast should almost never be used)

Both take a template parameter to the resulting type.

In this case, you could probably i = static_cast<int>(d);

For the second cast, j =, you should (in reality you shouldn't cast pointers to different types)

j = *reinterpret_cast<int*>(p);

Of course, casting doubles to integers isn't considered good, but this should fix your compiler error.

JohnkaS
  • 622
  • 8
  • 18
  • `*reinterpret_cast(p)` is UB and should not be used. – Evg Jun 07 '19 at 15:49
  • Agreed, it should not be used, agreed. He shouldn't be casting doubles to integers at all. I realise this is undefined behavior i just wanted to give an example on reinterpret_cast, he's better off doing `static_cast(*p)` in this case. – JohnkaS Jun 07 '19 at 15:51
  • 1
    Probably, I'm missing something, but `*reinterpret_cast(p)` and `static_cast(*p)` do completely different things. – Evg Jun 07 '19 at 15:54
  • Correct again, I wanted to give an example on reinterpret_cast, since I had just given the 2 main cast types in C++. – JohnkaS Jun 07 '19 at 15:55
  • "An integer only has 4 bytes, whereas a double has 8." Not necessarily. – Bathsheba Jun 07 '19 at 16:20
  • I wanted to say it's `implementation defined` but that would confuse him more, since he's clearly a beginner, though, ill add it to the post – JohnkaS Jun 07 '19 at 16:24
  • @Bapo: An answer ought not be targeted solely at the OP: it ought to be correct too. – Bathsheba Jun 07 '19 at 16:26
  • I also take issue with "A double has decimal numbers". Saying that a "double is a subset of the set of real numbers" is better. – Bathsheba Jun 07 '19 at 16:27
  • I disagree that's better for explaining the fact that an integer does not have decimals, so I won't be editing that. – JohnkaS Jun 07 '19 at 16:28
  • 2
    _"you should"_ then _"Agreed, it should not be used, agreed"_ – Lightness Races in Orbit Jun 07 '19 at 16:28
  • @Bapo: But saying that a `double` can hold decimal numbers is misleading. They can't in general: in that respect they are no better than an integral type. Sorry but the downvote stays. – Bathsheba Jun 07 '19 at 16:30
  • I mean, I didn't write this for reputation lol, keep the downvote there, couldn't care less. – JohnkaS Jun 07 '19 at 18:56