开发者

Casting between integers and pointers in C++

#include<iostream>
using namespace std;

int main()
{
  int *p,*c;
  p=(int*)10;
  c=(int*)20;
  cout开发者_如何学运维<<(int)p<<(int)c;
}

Somebody asked me "What is wrong with the above code?" and I couldn't figure it out. Someone please help me.


The fact that int and pointer data types are not required to have the same number of bits, according to the C++ standard, is one thing - that means you could lose precision.

In addition, casting an int to an int pointer then back again is silly. Why not just leave it as an int?

I actually did try to compile this under gcc and it worked fine but that's probably more by accident than good design.


Some wanted a quote from the C++ standard (I'd have put this in the comments of that answer if the format of comments wasn't so restricted), here are two from the 1999 one:

5.2.10/3

The mapping performed by reinterpret_cast is implementation defined.

5.2.10/5

A value of integral type or enumeration type can be explicitly converted to a pointer. A pointer converted to an integer of sufficient size (if ant such exists on the implementation) and back to the same pointer type will have its original value; mappings between pointers and integers are otherwise implementation-defined.

And I see nothing mandating that such implementation-defined mapping must give a valid representation for all input. Otherwise said, an implementation on an architecture with address registers can very well trap when executing

p = (int*)10;

if the mapping does not give a representation valid at that time (yes, what is a valid representation for a pointer may depend of time. For instance delete may make invalid the representation of the deleted pointer).


Assuming I'm right about what this is supposed to be, it should look like this:

int main()
{
  int *p, *c;
  // Something that creates whatever p and c point to goes here, a trivial example would be.
  int pValue, cValue;
  p = &pValue;
  c = &cValue;
  // The & operator retrieves the memory address of pValue and cValue. 

  *p = 10;
  *c = 20;
  cout << *p << *c;
}

In order to assign or retrieve a value to a variable referenced by a pointer, you need to dereference it.

What your code is doing is casting 10 into pointer to int (which is the memory address where the actual int resides).


addresses p and c may be larger than int.


The problem on some platforms you need

p = (int*) (long) 10;

See GLIB documentation on type conversion macros.

And for the people who might not find a use for this type of expressions, it is possible to return data inside pointer value returning functions. You can find real-world examples, where this case it is better to use this idiom, instead of allocating a new integer on the heap, and return it back - poor performance, memory fragmentation, just ugly.


You're assigning values (10 and 20) to the pointers which obviously is a potential problem if you try to read the data at those addresses. Casting the pointer to an integer is also really ugly. And your main function does not have a return statement. That is just a few things.


there is more or less everything wrong with it:

int *p,*c;
p=(int*)10;
c=(int*)20;
  • afterwards p is pointing to memory address 10
  • afterwards c is pointing to memory address 20

This doesn't look very intentional.

And I suppose that the whole program will simply crash.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜