Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Out of order initializer causes en error when compiling in C++

Hi,

I'm compiling a piece of code that uses USB CDC ACM from a .cpp file, and I stumbled on the compiler complaining about out of order initializers in app_usbd_cdc_acm_internal.h.

Error is triggered by the macro APP_USBD_CDC_ACM_INST_CONFIG, which is called by APP_USBD_CDC_ACM_GLOBAL_DEF.

Error shown below.

I am using SEGGER Embedded Studio for ARM Release 4.42  Build 2020012702.41180 Linux x64, and SDK 16.0.0. The project is derived from the Blinky example.

error: designator order for field ‘app_usbd_cdc_acm_inst_t::comm_interface’ does not match declaration order in ‘app_usbd_cdc_acm_inst_t’

To workaround this I had to modify app_usbd_cdc_acm_internal.h so it reads as follows : (basically I looked up the definition of the struct, and reordered initializers accordingly)

#define APP_USBD_CDC_ACM_INST_CONFIG(user_event_handler,                                         \
                                     comm_ifc,                                                   \
                                     comm_ein,                                                   \
                                     data_ifc,                                                   \
                                     data_ein,                                                   \
                                     data_eout,                                                  \
                                     cdc_protocol,                                               \
                                     ep_list)                                                    \
        .inst = {                                                                                \
                .comm_interface  = comm_ifc,                                                     \
                .comm_epin       = comm_ifc,                                                     \
                .data_interface  = data_ifc,                                                     \
                .data_epout      = data_eout,                                                    \
                .data_epin       = data_ein,                                                     \
                .protocol        = cdc_protocol,                                                 \
                .user_ev_handler = user_event_handler,                                           \
                .p_ep_interval   = ep_list                                                       \
        }

This, and the fact that I also had to move the definition of enum app_usbd_cdc_acm_user_event_e to this file to get rid of an inoperative forward declaration, leaves me pondering :

Do you officially support C++ compilation with your SDK ?

David Taillé

  • Hi,

    Do you officially support C++ compilation with your SDK ?

    There is no official support for C++, and the SDK is not tested with a C++ compiler.

  • Hi, NRF52 SDK works great with C++ with a few minor tweaks to the Makefiles :-

    --- old/nRF5_SDK_17.0.0_9d13099/components/toolchain/gcc/Makefile.common
    +++ new/nRF5_SDK_17.0.0_9d13099/components/toolchain/gcc/Makefile.common
    @@ -240,7 +240,7 @@ endef
     # MAKE in version prior to 4.0 does not provide the $(file ...) function.
     define dump
     $(eval CONTENT_TO_DUMP := $(1)) \
    -"$(MAKE)" -s --no-print-directory \
    ++"$(MAKE)" -s --no-print-directory \
     -f "$(TEMPLATE_PATH)/dump.mk" VARIABLE=CONTENT_TO_DUMP
     endef
     export CONTENT_TO_DUMP
    @@ -269,11 +269,11 @@ endef
     
     # Create object files from C source files
     %.c.o:
    -       $(call run,$(CC) -std=c99,$(CFLAGS),Compiling)
    +       $(call run,$(CC)         ,$(CFLAGS),Compiling)
     
     # Create object files from C++ source files
     %.cpp.o:
    -       $(call run,$(CXX),$(CFLAGS) $(CXXFLAGS),Compiling)
    +       $(call run,$(CXX),          $(CXXFLAGS),Compiling)
     
     # Create object files from assembly source files
     %.S.o %.s.o.o:
    @@ -291,7 +291,7 @@ endif
     %.out:
     $(info $(call PROGRESS,Linking target: $@))
     $(NO_ECHO)$(GENERATE_LD_INPUT_FILE)
    -       $(NO_ECHO)$(CC)  $(LDFLAGS) $(LD_INPUT) -Wl,-Map=$(@:.out=.map) -o $@
    +       $(NO_ECHO)$(CXX) $(LDFLAGS) $(LD_INPUT) -Wl,-Map=$(@:.out=.map) -o $@
     $(NO_ECHO)$(SIZE) $@
     
     # Create binary .bin file from the .out file
    

    (same patches work against latest 17.0.2 SDK)

    I have done multiple C++ projects with these minor changes and never had an issue, and all the C-only examples also work perfectly fine.

    Fwiw, I'm using my system arm-none-eabi-gcc which is currently v11.1.0.

    It's a little disappointing that you're so close to C++ support, but simply haven't taken the final step.

    PS: just checking in because I ran into OP's issue literally today - it's still present in 17.0.2, along with:

    In file included from /home/triffid/Projects/NRF/nRF5_SDK/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.h:58,
                     from ../../../../../HAL/NRF52/USB_CDC_ACM.cpp:10:
    /home/triffid/Projects/NRF/nRF5_SDK/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm_internal.h:68:6: error: use of enum 'app_usbd_cdc_acm_user_event_e' without previous declaration
       68 | enum app_usbd_cdc_acm_user_event_e;
          |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /home/triffid/Projects/NRF/nRF5_SDK/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm_internal.h:80:55: error: use of enum 'app_usbd_cdc_acm_user_event_e' without previous declaration
       80 |                                                  enum app_usbd_cdc_acm_user_event_e event);
          |                                                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    In file included from /home/triffid/Projects/NRF/nRF5_SDK/integration/nrfx/nrfx_glue.h:71,
                     from /home/triffid/Projects/NRF/nRF5_SDK/modules/nrfx/nrfx.h:46,
                     from /home/triffid/Projects/NRF/nRF5_SDK/modules/nrfx/drivers/include/nrfx_spi.h:44,
                     from ../../../../../HAL/NRF52/USB_CDC_ACM.cpp:3:
    ../../../../../HAL/NRF52/USB_CDC_ACM.cpp:27:57: error: invalid conversion from 'void (*)(const app_usbd_class_inst_t*, app_usbd_cdc_acm_user_event_t)' {aka 'void (*)(const app_usbd_class_inst_s*, app_usbd_cdc_acm_user_event_e)'} to 'app_usbd_cdc_acm_user_ev_handler_t' {aka 'void (*)(const app_usbd_class_inst_s*, int)'} [-fpermissive]
       27 |                                                         cdc_acm_user_ev_handler,
          |                                                         ^~~~~~~~~~~~~~~~~~~~~~~
          |                                                         |
          |                                                         void (*)(const app_usbd_class_inst_t*, app_usbd_cdc_acm_user_event_t) {aka void (*)(const app_usbd_class_inst_s*, app_usbd_cdc_acm_user_event_e)}
    /home/triffid/Projects/NRF/nRF5_SDK/components/libraries/util/app_util.h:586:32: note: in definition of macro 'BRACKET_EXTRACT__'
      586 | #define BRACKET_EXTRACT__(...) __VA_ARGS__
          |                                ^~~~~~~~~~~
    /home/triffid/Projects/NRF/nRF5_SDK/components/libraries/util/app_util.h:584:29: note: in expansion of macro 'BRACKET_EXTRACT_'
      584 | #define BRACKET_EXTRACT(a)  BRACKET_EXTRACT_(a)
          |                             ^~~~~~~~~~~~~~~~
    /home/triffid/Projects/NRF/nRF5_SDK/components/libraries/usbd/app_usbd_class_base.h:813:13: note: in expansion of macro 'BRACKET_EXTRACT'
      813 |             BRACKET_EXTRACT(class_config_part)                                          \
          |             ^~~~~~~~~~~~~~~
    /home/triffid/Projects/NRF/nRF5_SDK/components/libraries/usbd/app_usbd_class_base.h:946:9: note: in expansion of macro 'APP_USBD_CLASS_INSTANCE_INITVAL'
      946 |         APP_USBD_CLASS_INSTANCE_INITVAL(                                        \
          |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /home/triffid/Projects/NRF/nRF5_SDK/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm_internal.h:263:9: note: in expansion of macro 'APP_USBD_CLASS_INST_GLOBAL_DEF'
      263 |         APP_USBD_CLASS_INST_GLOBAL_DEF(                                                           \
          |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /home/triffid/Projects/NRF/nRF5_SDK/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm_internal.h:268:18: note: in expansion of macro 'APP_USBD_CDC_ACM_INST_CONFIG'
      268 |                 (APP_USBD_CDC_ACM_INST_CONFIG(user_ev_handler,                                    \
          |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /home/triffid/Projects/NRF/nRF5_SDK/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.h:166:5: note: in expansion of macro 'APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL'
      166 |     APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL(instance_name,                         \
          |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ../../../../../HAL/NRF52/USB_CDC_ACM.cpp:26:1: note: in expansion of macro 'APP_USBD_CDC_ACM_GLOBAL_DEF'
       26 | APP_USBD_CDC_ACM_GLOBAL_DEF(m_app_cdc_acm,
          | ^~~~~~~~~~~~~~~~~~~~~~~~~~~

    which can be fixed by simply moving the enum above #include "app_usbd_cdc_acm_internal.h" in components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.h

Related