RIanGillis
RIanGillis

Reputation: 619

Overcoming decltype Issues in Visual Studio 2013

I have been using the great bit-handling examples provided by @ddriver:

#define GETMASK(index, size) (((1 << (size)) - 1) << (index))
#define READFROM(data, index, size) (((data) & GETMASK((index), (size))) >>  (index))
#define WRITETO(data, index, size, value) ((data) = ((data) & (~GETMASK((index), (size)))) | ((value) << (index)))
#define FIELD(data, name, index, size) \
  inline decltype(data) name() { return READFROM(data, index, size); } \
  inline void set_##name(decltype(data) value) { WRITETO(data, index, size, value); }

taken from: How to read/write arbitrary bits in C/C++ , to do some amazing and wonderful things.

The problem I'm encountering is that most of my development work is done in VS 2015, where the above #defines work great, but not in VS 2013, which is my other dev environment, where upgrading is not an option at the moment.

I am pretty sure the issue is the calls to decltype(), as there are a couple SO questions related to that function and VS 2013 with a couple of different workarounds:

[Why is Visual Studio 2013 having trouble with this class member decltype? ]
[C++ decltype fails to deduce type ]
[Visual C++ - decltype as a return type of a class template's member function ]
[VS2013 Intellisense doesn't understand decltype ]
[How to use auto return and decltype when class members involved with c++11? ]

Unfortunately, I was unable to use any of the above solutions to solve my problem that does not involve upgrading the environment to VS 2015.
Any help would be greatly appreciated.

The errors I am receiving are thrown when compiling something similar to:

FIELD(bytes[0][0].r, layer1a, 1, 8);

I get the following errors:

error C2597: illegal reference to non-static member 'mBit::bP::bytes'
error C3867: 'mBit::bP::bytes': function call missing argument list; use '&mBit::bP::bytes' to create a pointer to member
error C2109: subscript requires array or pointer type

Modifying the bytes[][] object so it is not an array does not seem to help.

Upvotes: 1

Views: 271

Answers (1)

Surt
Surt

Reputation: 16109

I was wondering what the decltype does for you so I have tried to rewrite the code a little, this might not be what you were looking for as the types are always uint64_t.

#include <stdint.h>
#include <stdio.h>
#define GETMASK(index, size) (((1ULL << (size)) - 1ULL) << (index))
#define READFROM(data, index, size) (((data) & GETMASK((index), (size))) >>  (index))
#define WRITETO(data, index, size, value) ((data) = ((data) & (~GETMASK((index), (size)))) | ((value) << (index)))

#define FIELD(data, name, index, size) \
      inline uint64_t name() { return READFROM(data, index, size); } \
      inline void set_##name(uint64_t value) { WRITETO(data, index, size, value); }

struct A {
  uint16_t bitData;
  FIELD(bitData, one, 0, 1)
  FIELD(bitData, two, 1, 2)
};

int main() {
  struct A a;
  a.bitData = 2;

  uint16_t res = a.two();
  a.set_two(3);

  printf("res = %u\n", res);
  printf("a = %u\n", a.bitData);
}

check result at http://ideone.com/yWnlJu

Upvotes: 2

Related Questions