esp-idf icon indicating copy to clipboard operation
esp-idf copied to clipboard

bt_mesh_net_recv moved to header uses nested designated initializer that breaks C++ builds in IDF 5.5 (IDFGH-16414)

Open ghost opened this issue 5 months ago • 3 comments

Answers checklist.

  • [x] I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
  • [x] I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
  • [x] I have searched the issue tracker for a similar issue and not found a similar issue.

IDF version.

v5.5.1 (also on v6.0.0)

Espressif SoC revision.

esp32s3

Operating System used.

Linux

How did you build your project?

VS Code IDE

Problem Description

Upgrading from IDF 5.4 to 5.5 causes C++ compilation to fail when any C++ TU indirectly includes BLE-Mesh headers. The failure originates in components/bt/esp_ble_mesh/core/net.h where bt_mesh_net_recv is now static inline and initializes a nested member via a designated initializer:

struct bt_mesh_net_rx rx = { .ctx.recv_rssi = rssi };

This is valid in C but not in C++ (nested designators are not supported), producing:

/opt/esp/idf/components/bt/esp_ble_mesh/core/net.h:475:34: error: expected primary-expression before '.' token
  475 |     struct bt_mesh_net_rx rx = { .ctx.recv_rssi = rssi };
      |                                  ^

Prior to commit a86bb375f7f23f2983f03b054f0c348f129de333 the function resided in a C source file net.c, so C++ never parsed this initializer. Moving it inline into net.h surfaced the C-only pattern to C++ TUs. Link to commit

Minimal reproduction

Create a C++ source that includes Mesh headers (even under extern "C"):

extern "C" {
#include "esp_ble_mesh_config_model_api.h"
}
int main() { return 0; }

Build under IDF 5.5. The build fails in .../core/net.h at the nested designator line. C++ designated initializers do not allow nested designators; this is per C++ standard and widely implemented by compilers.

What changed

The BLE-Mesh refactor introduced a static inline bt_mesh_net_recv in net.h. That inline uses a nested designated initializer .ctx.recv_rssi.

Expected behavior

C++ TUs should compile when consuming ESP-BLE-Mesh public headers, or at least headers should avoid C-only constructs when inlined into headers consumed by C++. Historically this compiled because the code lived in C .c files.

Actual behavior

C++ compilation fails with:

/opt/esp/idf/components/bt/esp_ble_mesh/core/net.h:475:34: error: expected primary-expression before '.' token
  475 |     struct bt_mesh_net_rx rx = { .ctx.recv_rssi = rssi };
      |                                  ^

Suggested fixes

Any of the following:

  1. Keep bt_mesh_net_recv in a C source net.c rather than an inline header, restoring prior behavior.
  2. Make the inline C++-friendly:
struct bt_mesh_net_rx rx = {0};
rx.ctx.recv_rssi = rssi;
bt_mesh_generic_net_recv(data, &rx, net_if);
  1. Guard with #ifdef __cplusplus to use the two-statement form only for C++.

Additional details

I am aware that the BLE-MESH module doesn't support C++ as is, but with minimal work I got it to work and I've been running it without issues for over 2 years.

ghost avatar Sep 08 '25 17:09 ghost

Any update ?

ghost avatar Oct 02 '25 19:10 ghost

HI, @AntoineSX

Sorry for the long delay in getting back to you and many thanks for being patient. and thank you very much for your report and suggestions, we will fix the problem in the future.

forx157 avatar Oct 11 '25 03:10 forx157

Thank you !

ghost avatar Oct 14 '25 13:10 ghost