2

I want to cast a void pointer to struct reference.

Minimum example with a struct:

#include "Interface.h"

class Foo
{
public:
   Foo()
   : mAddress((uint32_t*)0x0803D000)
   // Okay
   , mStructPtr(*static_cast<const Struct*>(mAddress)) 
   // Error: invalid static_cast from type 'const void*' to type 'const Struct&
   , mStructRef1(static_cast<const Struct&>(mAddress))
   // Error: 'const void*' is not a pointer-to-object type
   , mStructRef2(static_cast<const Struct&>(*mAddress)) 
   {

   }

private:
   const void * const mAddress;
   Struct* mStructPtr;
   Struct& mStructRef1;
   Struct& mStructRef2;
};

Is it meaningful/possible to use the reference (how to initialize in constructor?) or do I have to use a pointer?

ge45mue
  • 677
  • 8
  • 23
  • 3
    Why do you have a `void*` in the first place? That is really dangerous as it looses all type information. You *can* try to use `reinterpret_cast` but that invokes *undefined behavior* if the `void*` did not point at an object of the correct type – UnholySheep Oct 26 '17 at 11:13
  • 5
    Are you working with a particular embedded platform/compiler? That first cast is a complete no-go for general C++, but if you're using a particular implementation, it might be OK, and you should tell us so that we don't just spend the entire thread criticising that one detail. More basically: How can anyone answer whether you can do the cast, without you telling us what is really at that address and how it was put there? Sure, we can probably resolve any syntax errors, but that doesn't mean the resulting code is guaranteed not to explode. – underscore_d Oct 26 '17 at 11:14
  • Sorry I have to change some information in my question. mAddress should be platform independent. I look if the problem is the same, when removing void with unsigned int and give an update. – ge45mue Oct 26 '17 at 11:17
  • 1
    Cast it to the pointer then dereference that pointer in the constructor to initialise the reference. – JCx Oct 26 '17 at 11:19
  • 2
    But it isn't platform independent as most platforms don't have an integer at that address. And then all of this is invalid. – Bo Persson Oct 26 '17 at 11:19
  • Possible duplicate of [How to cast/convert pointer to reference in C++](https://stackoverflow.com/questions/10172735/how-to-cast-convert-pointer-to-reference-in-c) – SwiftMango Oct 26 '17 at 11:19
  • There is no platform-independent, Standard C++ way to create/retrieve/magically-construct-on-demand an object at a specific numerical location in memory. – underscore_d Oct 26 '17 at 11:22
  • What's wrong with class Foo { Foo() : s(*reinterpret_cast(0x0803D000)) {} Struct & s; }; ... assuming that struct already exists at that memory location in an appropriate format. – JCx Oct 26 '17 at 11:27
  • Thank you JCx for your hint! Solution: mStructRef1(*static_cast(mAddress)) – ge45mue Oct 26 '17 at 11:27
  • @JCx I'll say it again: we can probably resolve any syntax errors, but that doesn't mean the resulting code is guaranteed not to explode. Or am I missing a detail? Does anything in the Standard make allowances for casting integers to pointers and getting any kind of reliable result? (i.e. enforcing that the OS must either allow allocating/retrieving from a given location, or at least signal an error in a predictable way) – underscore_d Oct 26 '17 at 11:28
  • @undersorce_d I know this is not okay. Maybe it doesn't look so nice, because this is a minimum example. But thank you for your necessary comment. – ge45mue Oct 26 '17 at 11:32
  • @underscore_d I don't think anyone is disagreeing with you, but sometimes you work with the environment you have not the environment defined by the standard. It depends what you are trying to do... – JCx Oct 26 '17 at 13:12

1 Answers1

0

I'm going to stick my neck out here and say this is the basics of what you are trying to do:

class Struct { int x;};

class Foo
{
    Foo() :
    s(*static_cast<Struct *>(reinterpret_cast<void*>(0x0803D000)))
    {}
    Struct & s;
};

(And this isn't portable across platforms - see all the comments).

JCx
  • 2,689
  • 22
  • 32