Not necessarily. But even if it did, C couldn't correctly cast it, since it has no knowledge about class hierarchies. It would behave like reinterpret_cast in C++, which is here undefined behaviour, if the resulting pointer is used.
It doesn't have to know about the class hierarchies. I've worked around low-level in the memory before and it has always worked like I described. I don't know if it's decided in the C++ standard but every C++ compiler(VC++, GCC, DM) I've worked with defines the first parent to be at offset
ptr + 0 and the next parents at
ptr + sizeof( firstParent + ... ) and finally the current class at
ptr + sizeof( firstParent + ... + nParent.
I've even created my own OO system in C which worked exactly like C++ with inheritance and I even succeeded with a vtable. I even added pre-parsing to it to create a proper language. And the inheritance was done by placing the parent first in the class. And this worked with up-casting as well. And this code was fully legitimate and C++ works the same way:
struct AClass
{
int foo;
};
struct BClass
{
struct AClass _parent;
int bar;
};
struct BClass bObject;
bOBject.bar = 5;
struct AClass *parent = ( struct BClass *)&bObject;
parent->foo = 10;
assert( bObject._parent.foo == 5 ); // Will be true
assert( bObject.bar == 10 ); // will be true
I'm not just talking out of my hat and making this up. I have verified all of this with extensive testing on all the compilers available to me. Both on C and C++. For heck's sake, I have even created a small GC experiment in C/C++, and when debugging that I really had to print out the exact memory layout in several different cases and check how to handle it. The only thing I don't handle in it is to find the end of the stack-frame.
Again, the cast to sfWindow* is undefined. Apart from that, no one guarantees that the sf::RenderTarget member begins sizeof(sfWindow) bytes after the beginning. You make assumptions about an implementation detail of both the compiler and the SFML library.
No it is not really undefined, all it does is look at a piece of memory in a new way. I'm not making that big of assumptions. But you are starting to in the next few rows. But you are right, I have no guarantee that the next class is placed directly after
sizeof(sf::Window) but it's the simplest way to do it for it compiler programmers so why wouldn't they? It seems to work for me. And you are focusing too much on this part which was not part of the question. It was just a quick idea that I know works and yes the casting is low and dirty but I don't propose that the C developer does it himself it should of course be hidden from the interface. And I think the possibilities are big enough for it to be implemented since the latest changes to the graphics interface. Because there is so much inheritance there now that you would like to take use of. Hey this would even allow C developers to create their custom Drawables among other things. It would give C developers the full functionality of C++ SFML and also ease of use. Now instead of writing
X functions for each kind of Transformable they will just have to write one single one.
Furthermore, the char array + placement new approach requires proper alignment, which is problematic when allocated on the stack.
No it is not? And now you are really starting to make assumptions. C doesn't allow the SFML objects to be allocated on the stack. And you are completely off here. Doesn't matter if it's in the heap or the stack the object is looks the same when just looking at the memory. But it differs in how it is allocated and how it's placed relative to other objects. But that is irrelevant for this question.
One cannot even perform an explicit upcast since sfWindow and sfRenderWindow are completely unrelated. They both contain a value member (sf::Window and sf::RenderWindow, correspondingly), so one would have to copy the instance, which is not possible.
Uh whut? I've done it several times. Either your not making yourself very clear or you are living on another planet.
The definition is:
struct sfWindow
{
sf::Window This;
};
Which means by the definitions of how C-style casting works and what I described before that this works just perfectly:
sfWindow *windowPtr = sfWindow_Create( /* foobar */ );
sf::Window *windowObj = (sf::Window *)windowPtr;
The only thing C has to do is to respect C++ memory layout which I've already defined. As long as it does that C++ will work as intended.