Why can't pointer fit variable of different type, even though sizeof is same?

假如想象 提交于 2019-12-25 19:01:28

问题


Why the sizeof any pointer is 4 or 8 bytes, but it cannot fit any different variable? I get error while trying to assign a double pointer an int pointer value.

int          *int_ptr{nullptr};
float        *float_ptr{nullptr};
double       *double_ptr{nullptr};
long double  *long_double_ptr{nullptr};
string       *string_ptr{nullptr};
vector<int>   *vector_ptr{nullptr};

cout << "sizeof int pointer is " << sizeof int_ptr;    //8 or 4
cout << "sizeof float pointer is " << sizeof float_ptr;    //8 or 4
cout << "sizeof double pointer is " << sizeof double_ptr;    //8 or 4
cout << "sizeof double double pointer is " << sizeof long_double_ptr;    //8 or 4
cout << "sizeof string pointer is " << sizeof string_ptr;    //8 or 4
cout << "sizeof vector int pointer is " << sizeof vector_ptr;  //8 or 4

double double_num{1020.7};
double_ptr = &int_ptr;      //cannot convert ‘int**’ to ‘double*’ in assignment

回答1:


C++ is a statically typed language. The language enforces type safety and protects you from mistakes by rejecting arbitrary conversions between unrelated types. The meaning of a type is not wholly described by the size alone.

If an address contains an object of type int*, then a int** can point to that object. Given that the address contains an object of type int*, it cannot possibly also contain an object of type double, so there is no meaningful way to convert one of those pointers to another.




回答2:


Pointers are addresses. Let's say, you have two addresses:

  1. 53 Main avenue
  2. 85 WrongTurn Road

The first one is the address to a small 2 bedrooms house. The second is the address is to a mansion, 23 bedrooms, 10 bathrooms, etc...

You cannot expect all people living in the mansion to move into the small house rigth? but guess what? at the post office, their box sizes is just the same! That's how they work. They just tell you where to find your variable. Thay are not containers




回答3:


This code is illegal because there is no "implicit conversion" to map from &int_ptr to double_ptr, where an "implicit conversion" is defined as something:

Performed whenever an expression of some type T1 is used in context that does not accept that type, but accepts some other type T2; in particular:

  • when the expression is used as the argument when calling a function that is declared with T2 as parameter;
  • when the expression is used as an operand with an operator that expects T2; when initializing a new object of type T2, including return statement in a function returning T2;
  • when the expression is used in a switch statement (T2 is integral type);
  • when the expression is used in an if statement or a loop (T2 is bool). The program is well-formed (compiles) only if there exists one unambiguous implicit conversion sequence from T1 to T2.

I initially suggested you use a reinterpret_cast but this won't work either as using the result of a reinterpret_cast between types is only legal if the types differ only by whether their signed, the type being cast to is a byte*, char*, or unsigned char*, or the types are "similar" which is defined as:

  • they are the same type; or
  • they are both pointers, and the pointed-to types are similar; or
  • they are both pointers to member of the same class, and the types of the pointed-to members are similar; or
  • they are both arrays of the same size or both arrays of unknown bound, and the array element types are similar.

As you can see none of these situations apply to wanting to cast from the address of int* int_ptr to double* double_ptr. It's difficult for me to predict your use case for this type of cast within a strongly typed language, but perhaps a void* is what you're looking for? It could point to either a valid int**, in which case you could initialize it like this: const void* ptr = reinterpret_cast<void*>(&int_ptr) or a valid double* in which case you'd initialize it like this: const void* ptr = reinterpret_cast<void*>(double_ptr). Of course in order to use ptr you'd need a variable telling you which type it contained, for example:

if(is_int) {
    // recover int** (reinterpret_cast<const int* const*>(ptr)) and operate on it
} else {
    // recover double* (reinterpret_cast<const double*>(ptr)) and operate on it
}

Live Example

I should admit at this point that this answer is somewhat contrived. A better solution anywhere this code is used would very likely be a template.



来源:https://stackoverflow.com/questions/55573060/why-cant-pointer-fit-variable-of-different-type-even-though-sizeof-is-same

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!