0

I am working on an IoT project and using ESP32 as a microcontroller for my devices.

This simple struct in c++ stores the basic state of a device:

struct DeviceState {
    char UID[12];
    DeviceMode mode;
    DeviceErrorType errorCode;
    char errorReason[256];
    char name[64];
};   // <--- this is line #28

UPDATE:missing types

enum DeviceMode {
        DEVICE_MODE_DEFAULT = 0,
        DEVICE_MODE_SETUP = 1,
        DEVICE_MODE_WORK = 2,
        DEVICE_MODE_FAILURE = 4
    };

enum DeviceErrorType {
        DEVICE_OK = 0b00000000,
        DEVICE_FATAL_ERROR = 0b10000001,
        DEVICE_INVALID_STATE = 0b00000010,
        DEVICE_SENSOR_ERROR = 0b00000011
    };

I use char arrays and not char*/std::string/String, because this state data will be saved in ESP32 flash, and i find char arrays a good choice. What I really want and have problems with is that if I want to define a default deviceState (which never changes, and will be copied to the current state when device resets)

DeviceState defaultDeviceState = {
    .UID = "undefined",
    .mode = DeviceMode::DEVICE_MODE_SETUP,  // just an enum
    .errorCode = DeviceErrorType::DEVICE_OK, // also enum
    .errorReason = "",
    .name = "noname"
};

I get the following error message:

WebSetupConsts.h: 28:5: error: C99 designator 'UID' outside aggregate initializer
WebSetupConsts.h: 28:5: error: C99 designator 'errorReason' outside aggregate initializer
WebSetupConsts.h: 28:5: error: C99 designator 'name' outside aggregate initializer

WebSetupConsts.h:28: sorry, unimplemented  non-trivial designated initializers not supported
WebSetupConsts.h:28: sorry, unimplemented  non-trivial designated initializers not supported
WebSetupConsts.h:28: sorry, unimplemented  non-trivial designated initializers not supported

I understand the error message, but for another initialization of a different struct having char* as members, this would work:

ConnectionData connData = {
        { .mqttServer = "4x.1xx.2xx.2xx" },
        { .mqttUsername = "xxxxxxxx" },
        { .mqttPassword = "password" },
          .mqttPort = 1883,
        { .wifiSSID = "UPCxxxxxxx" },
        { .wifiPassword = "xxxxxxxxxx" }
    };

Wrapping char* members in {} brackets works, but it won't work with char[].

Can someone explain me, why it won't work for char arrays? Is there any way to define a struct having char arrays, and initialize it using designated initializer(member names)?

Using a different initialization won't work either:

DeviceState defaultDeviceState = {
    "undefined",
    DeviceMode::DEVICE_MODE_SETUP,
    DeviceErrorType::DEVICE_OK,
    "",
    "noname"
};

The error message is:

WebSetupConsts.h: 28:5: error: invalid conversion from 'const char*' to 'char' [-fpermissive]
WebSetupConsts.h: 28:5: error: invalid conversion from 'const char*' to 'char' [-fpermissive]

Then how can I initialize it?

And the last question is: if this is not the best way to store device state, what is?

I know i have too many questions, but I really want to understand c++, thanks for the answers. The compiler is: xtensa-esp32-elf-gcc 1.22.0-80-g6c4433a-5.2.0

zak
  • 115
  • 1
  • 9
  • Exactly which line is line 28 of the file `WebSetupConsts.h`? Please add a comment on that line so we know which it is. And do you only get an error that exact line? No more errors for the other strings? And if possible, please try to create a [mcve] to show us, as well as adding the options you pass to the compiler. – Some programmer dude Feb 24 '21 at 22:19
  • 1
    Designated Initializers require C++20 (though some compilers may have incorporated them as an extension before that). For your last attempt: I cannot reproduce your error, and that is what I would use myself. – Adrian Mole Feb 24 '21 at 22:22
  • Can you show us what your `DeviceMode` and `DeviceErrorType` types are? And the `DEVICE_MODE_SETUP` and `DEVICE_OK` values. They would seem to be the cause of your errors in the last snippet. – Adrian Mole Feb 24 '21 at 22:24
  • sorry, i have updated the text above with missing info – zak Feb 24 '21 at 22:33
  • OK, using your two `enum` definitions, code using your last snippet to initialize a structure compiles without error or warning in Visual Studio 2019 (with either MSVC or clang-cl). And, as far as I can see, it *should* compile without error or warning. You don't, perhaps, have some 'leftover' extra braces in your initialization? – Adrian Mole Feb 24 '21 at 22:52
  • @AdrianMole thanks for your help, at least it made me more confident, that I am not that stupid, and what I thought how C++ should work is not wrong. I'll check the code looking for another problems that can cause it. – zak Feb 24 '21 at 23:23

0 Answers0