0

In a library I have come across a weird construction which serves as enum:

typedef struct SetControl
{
  const static uint16_t RC_MODE_ERROR;
  const static uint16_t RELEASE_CONTROL_SUCCESS;
  const static uint16_t OBTAIN_CONTROL_SUCCESS;
  const static uint16_t OBTAIN_CONTROL_IN_PROGRESS;
  const static uint16_t RELEASE_CONTROL_IN_PROGRESS;
  const static uint16_t RC_NEED_MODE_F;
  const static uint16_t RC_NEED_MODE_P;
  const static uint16_t IOC_OBTAIN_CONTROL_ERROR;
} SetControl;

The members are not initialized anywhere but even though, RC_MODE_ERROR equals 0, RELEASE_CONTROL_SUCCESS equals 1 and so on. I know because I have logged it with printf. I haven't seen anything like it so far. Why does it even work (I thought values will be initialized by random data by default, or 0)? Is there any add value from this over standard enum?

What can I try next?

halfer
  • 19,824
  • 17
  • 99
  • 186
Łukasz Przeniosło
  • 2,725
  • 5
  • 38
  • 74
  • 3
    @EdChum but this is not declared as an enum. These are members of a struct – Basya Sep 07 '17 at 12:24
  • 2
    Those values _have to_ be defined somewhere, somehow. Keep digging! – YSC Sep 07 '17 at 12:25
  • 2
    They look like macros they are probably macro defined somewhere, is there some `#define ...` somewhere – EdChum Sep 07 '17 at 12:26
  • 1
    Are you sure there isn't a cpp file that doesn't set these static members? What you are seeing should not happen unless it is coded to do so. – NathanOliver Sep 07 '17 at 12:26
  • @EdChum how exactly do they _look like macro_? Is it because they are all uppercase? – YSC Sep 07 '17 at 12:26
  • I agree with what @EdChum said. Normally, those members would be [initialized to 0](https://stackoverflow.com/a/6032696/7571171) – Thomas Flinkow Sep 07 '17 at 12:26
  • 2
    @EdChum it's OK, I think we all do that sometimes – Basya Sep 07 '17 at 12:27
  • @YSC yes, it's not required but it's a convention I've seen and used – EdChum Sep 07 '17 at 12:27
  • @EdChum it is conventional to name macro identifiers with all caps, but all caps identifiers are not necessarily macros ;) I see nothing that hints to a macro definition here. – YSC Sep 07 '17 at 12:29
  • @YSC true but this isn't exactly an MVCE anyway, looking at it I suspect these are macro defined – EdChum Sep 07 '17 at 12:30
  • @YSC OK they're not macros but scoped consts – EdChum Sep 07 '17 at 12:31
  • @EdChum This is a possible explanation, but you wrote _"They look like macros they are probably macro"_ and I disagree with that. This is not _"probably macro"_, it _might_ be macros. – YSC Sep 07 '17 at 12:31
  • The code base where you found it predates C++11, most probably. This is a poor-man's scoped enumeration with an underlying type. Nowadays we'd opt to write it as `enum class SetControl : std::uint16_t { ... };`. Also that `typedef` is completely superfluous. – StoryTeller - Unslander Monica Sep 07 '17 at 12:57

2 Answers2

7

To begin with, this is not an enum, this is a struct. These are different concepts, but I think you knew, just got confused by the usage here.

It is not expected for the members of a struct to be assigned to these values (as for example would happen with an enum).

I am fairly sure that these members get initialized somewhere in your code, or they are Macros, thus are defined somewhere.


After searching Github, they are initialized, like this:

const uint16_t DJI::OSDK::ErrorCode::ControlACK::SetControl::RC_MODE_ERROR = 0x0000;
const uint16_t DJI::OSDK::ErrorCode::ControlACK::SetControl::RELEASE_CONTROL_SUCCESS = 0x0001;
const uint16_t DJI::OSDK::ErrorCode::ControlACK::SetControl::OBTAIN_CONTROL_SUCCESS = 0x0002;
const uint16_t DJI::OSDK::ErrorCode::ControlACK::SetControl::OBTAIN_CONTROL_IN_PROGRESS = 0x0003;
const uint16_t DJI::OSDK::ErrorCode::ControlACK::SetControl::RELEASE_CONTROL_IN_PROGRESS = 0x0004;
const uint16_t DJI::OSDK::ErrorCode::ControlACK::SetControl::RC_NEED_MODE_F = 0x0006;
const uint16_t DJI::OSDK::ErrorCode::ControlACK::SetControl::RC_NEED_MODE_P = 0x0005;
const uint16_t DJI::OSDK::ErrorCode::ControlACK::SetControl::IOC_OBTAIN_CONTROL_ERROR = 0x00C9;

in dji_error.cpp.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
-1

Static members needs to be separately defined.

Ex:

// in example.h
struct SetControl
{
    const static uint16_t RC_MODE_ERROR; // this is only a declaration
};

// in example.cpp
const uint16_t SetControl::RC_MODE_ERROR = 1; // this is the definition
sp2danny
  • 7,488
  • 3
  • 31
  • 53