Reputation: 2720
I have come across some code that looks like it is forward declaring a struct but I can not find any definition for the struct in the code base. It seems to be used as though the struct was defined. Could someone explain why the below code is valid c++?
What type is Frame? What is the size? I cannot use sizeof() as it will complain it is undefined.
I am trying to convert a similar piece of code to Visual Studio 2015 from 2010. The reinterpret_cast cast is complaining that it cannot be converted due to the fact that
'reinterpret_cast': conversion from 'unsigned long' to 'Frame *' of greater size
#include <stdio.h>
struct Frame;
int main()
{
unsigned long currentFrame = 5;
Frame* frame = reinterpret_cast<Frame*>(currentFrame);
printf("%p", frame);
}
GCC 4.9.2 was used to compile this example.
I understand the error, but do not understand how the struct is being used. Is it defaulting to int?
Upvotes: 1
Views: 140
Reputation: 234685
The program behaviour is undefined, as a conversion from an unsigned long
to Frame*
where the former is set to a value not associated with a pointer value that you can set is not in accordance with one of the possibilities mentioned in http://en.cppreference.com/w/cpp/language/reinterpret_cast.
The fact that printf
appears to output the address of a pointer is a manifestation of that undefined behaviour.
The fact that Frame
is an incomplete type does not matter here. With the exception of nullptr
, one past the address of a scalar (i.e. single object or a plain-old-data object), and one past the end of an array, the behaviour on setting a pointer type to memory you don't own is also undefined.
Upvotes: 3
Reputation: 133577
Since you are using Frame
just as a pointer the compiler doesn't need to know anything about Frame
structure itself. It's like using an opaque pointer to something without caring what's pointed.
The cast fails because unsigned long
is not guaranteed to be the same size of a pointer according to operating system and data model (eg LLP64 vs LP64). You should consider using intptr_t
from <stdint.h>
which is guaranteed to be able to store all the bits of a pointer but I don't see how you could need to reinterpred a literal to a memory address.
Upvotes: 2