tags:

views:

726

answers:

4

The offsetof macro seems not to work under C++/CLI.

This works fine in unmanaged C++, but throws "error C2275: 'Entity' :illegal use of this type as an expression" error in CLI.

struct Property{
     char* label;
     PropertyTypes type;
     unsigned int member_offset;
     unsigned int position;
     unsigned char bit_offset;
};

struct Entity{
     ...
     bool transparent;
     ...
};

Property property = {"Transparent",  
       TYPE_BOOL,    
       offsetof(Entity, transparent), 
       0, 
       0}; // C2275 HERE

Does CLI have some replacement?

A: 

You will need to provide the type of the object you are assigning to. Looks like there is some type-mismatch for the member in question.

See this for sample usage.

dirkgently
+1  A: 

Just a shot in the dark and without a chance to double-check this - should

offsetof(Entity, transparent),

perhaps rather read

 offsetof( struct Entity, transparent ),

???

DevSolar
Spot on. His mistake probably arises from most code out there doing a typedef of the struct.
alecco
+1  A: 

Standard C++ already has an alternative; &Entity::transparent. You'll probably want to use templates when redesigning the Propery class. The type of a pointer-to-member is non-trivial.

MSalters
+2  A: 

My guess would be that the compiler message boils down to: "offsetof" is not a known macro and if it was a function its parameters must not contain a typename.

Edit: As somebody pointed out in the comments, offsetof is actually part of the std lib. So what's missing is probably just

#include <cstddef>

Alternatively, you can use this macro implementation (taken from Win32/MFC headers):

#ifdef _WIN64
    #define OFFSET_OF( s, m )\
      (size_t)((ptrdiff_t)&reinterpret_cast<const volatile char&>((((s*)0)->m)) )
#else
    #define OFFSET_OF( s, m )\
      (size_t)&reinterpret_cast<const volatile char&>((((s*)0)->m))
#endif
<cstddef> is part of the C++ standard...
DevSolar
...that is, assuming he *does* actually include it...
DevSolar
Defining your own macro could prevent the compiler from using an intrinsic implementation. For POD that doesn't matter (and the standard only guarantees offsetof will work for POD anyway). But some compilers have an intrinsic that can handle non-POD types correctly, giving a compile-time constant expression even for a class that uses multiple or virtual inheritance. That kind of thing tends to crash macro implementations at run-time.
Steve314