nRFConnect Examples fail to build with C++17

Greetings,

We've run into issues while trying to get the nRFConnect v2.4.0 examples to build for a C++17 project. The problem is easy to replicate by:

  1. Create an example project for LLPM in VSCode/nRFConnect
  2. In KConfig enable C++ Support and select C++17
  3. Rename main.c to main.cpp
  4. Update CMakeLists.txt to include src/main.cpp
  5. Attempt a pristine build
  6. Observe Terminal Output

It looks like there are a number of issues (all fairly minor?) including:

  • Designator order for struct initialization not matching declaration order
    • Easy enough to reorder
  • Poorly designed/unnecessary macros resulting in utilizing addresses of temporary arrays
    • The macros just initialize an array of structures... so we can just use the standard C code way of doing that and eliminate multi-level macros
  • Invalid C-style conversations from void* to typedef struct pointers
    • For our project we can use the appropriate C++ style casts (static_cast or reinterpret_cast). I'm not sure how to make that C-compliant
    • Note that there are a number of C-style casts to void* deep inside the macro-chain. This can hide some fairly nasty bugs like casting a value to void* instead of the intended pointer to the value.

It's not a huge deal to make the fixes, but it's fairly frustrating for example projects to not build out of the box. The "helper" macros make things worse since the identifying the real bug requires diving down multiple layers and reengineering the intent to make the example compile.

Please let me know if you're able to replicate this or have an easy solution I'm missed.

Thanks!

  • I feel your frustration too. I was hopeful to see something being mentioned along the lines of C++ being supported. But you really have to jump through hoops and rework the massive amount of macro usages to play nice with C++.

    I am now second guessing my original plan to utilize C++...which is a shame.

  • Hi,

    I'm definitely to reproduce this, thanks for the clear instructions. From these kind of Kconfig options one would think that C++ is fully supported in Zephyr but unfortunately that really doesn't seem to be the case. I understand your frustration.

    I haven't dealt with this much (the customers I've come across have almost exclusively worked with C) so I don't have any easy solutions at hand, but I'll ask the NCS team and see if they have anything I could share with you.

    Best regards,

    Raoul

  • I was able to get this project to build in C++17, but the macro issue mentioned above was not trivial. I had to decipher the intent of some TERRIBLY designed macros to actually declare and initialize structure values. Note that there is ZERO documentation on this so I had to dig through many layers of nested macros to even figure out what they were attempting to do.

    See below for how I ended up declaring and initializing the structures. This take the place of the previous definitions of the UUID and LE_ADV structure.  In my own code I'll likely eliminate the INIT macros as well to avoid code obfuscation. Structures could just be initialized with standard initializers and not 5-10 layers of macros. I suggest looking at ST Micro's Low-Level (LL) libraries for the creation, initialization, and passing of structures for peripheral setup.

    Note that this will be required for every C++ project that uses BLE (essentially every Nordic project). I suggest that Nordic quickly addresses this issue since the typical programmer who isn't vendor locked, doesn't have enough experience in both C and C++, or isn't stubborn enough won't be able to get this to work. Ideally they would also press the Zephyr development to reduce/eliminate the use of these unnecessary macros to make for more readable and reliable code.

    const struct bt_uuid_128 BtUUIDLatency = BT_UUID_INIT_128(BT_UUID_LATENCY_VAL);
    const struct bt_le_adv_param BtLEAdvConn = BT_LE_ADV_PARAM_INIT(BT_LE_ADV_OPT_CONNECTABLE,BT_GAP_ADV_FAST_INT_MIN_2,BT_GAP_ADV_FAST_INT_MAX_2,NULL);

  • Hi John,

    Thanks a lot for the details, I appreciate you sharing them with the rest of DevZone.

    Just so you know, your frustrations have been brought up with our NCS developers.

    If I hear anything of use to you, I'll share it here.

    By the way, I'll be out-of-office for the next 2 weeks, so if you should have any follow-up questions I recommend you make a new ticket.

    Best regards,

    Raoul

Related