2026-01-24 12:59 AM
It is very inconvenient to have regenerated C files in C++ project.
Problem is not main.c only, *_it.c as well. In C++ project one have to call methods of class from interrupt handlers.
It is not possible to make directly from *_it.c. Indirect call chain is lost of time.
I renamed main.c to main.cpp in C++ project, made call from main.cpp to method of class. All is OK.
Flashed microcontroller with main.cpp, all is working.
ST done great work to support C++. And made it useles by generating new code to C files. Why not to generate code in C++ project to CPP files?
Solved! Go to Solution.
2026-01-25 11:58 PM
Hello @vybor
CubeMX always generates core files like main.c and stm32xx_it.c in C, even in “C++ projects”, because the HAL, startup code and examples are all C and ST wants maximum compatibility and simpler support.
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2026-01-25 11:58 PM
Hello @vybor
CubeMX always generates core files like main.c and stm32xx_it.c in C, even in “C++ projects”, because the HAL, startup code and examples are all C and ST wants maximum compatibility and simpler support.
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2026-01-26 1:43 AM - edited 2026-01-26 2:30 AM
Regenerated stm32xx_it.c is headache in C++ project, it prevents to make efficient direct calls to C++ objects from C handlers.
Fathermore, long single file with a lot of unrelated functionality is bad also.
It should be better to have separate file for each handler in subdirectory.
I try such approach, one handler in separate CPP file. Cutoff a handler from stm32xx_it.c and
save it in CPP file, all is OK.
As to main.c, right main.c schould have one line of user code like app_c(), wich
is never changed to prevent spagetti of generated and user code.
Modern C++ with propper use of templates, constexpr and other features is much better for
embedded programming.
The HAL, startup code and examples runs from main.cpp.
main() in C file and extern "C" main() in CPP are the same functions.
It is time to rethink code generator. ESP32 have C++23 from the box, fully functional.
2026-01-27 9:18 AM - edited 2026-01-27 9:19 AM
Many users are accustomed to the existing system (and still consider C as a decent language). They would object.
On the other hand, everyone can tweak their projects as they like.
2026-01-27 9:27 AM
You can configure CubeMX to not generate the handlers - then you can write them how you like and where you like.
@vybor wrote:As to main.c, right main.c schould have one line of user code like app_c(), wich
is never changed to prevent spagetti of generated and user code.
You can do that if you want - see, for example:
2026-01-29 1:45 AM
Why not to give to developer oportunity to select C or CPP files from code generator?
ST make good controllers but software far from good.
Code genarator created without efficiency of resulting code in mind.
A lot of surplus data structures, data movement, runtime execution.
Initialization is bad. All initialization parameters are compile time constant
and all functionality of runtime init functions (say, MX_GPIO_Init and LL_GPIO_Init) can and must be done at compile
time. No need to create and fill GPIO_InitStruct structures and have runtime overhead.
Parameters from desing tool must be checked at complie time and not need runtime checks. In current design a lot of asserts.
It is common approach.
After removing Device Configuration Tool from CubeIDE 20 it became unusable.
I can compile ESP32 code with C++23 without any problem. ST have ancient C only.
2026-01-29 1:54 AM
@vybor wrote:After removing Device Configuration Tool from CubeIDE 20 it became unusable.
The configuration tool and the code it generates have not changed - only the fact that it's no longer integrated.
2026-01-29 7:33 AM
It's awfully inconvenient to switch from IDE to Tool Configurtion time after time.
It's seems that decision makers far from development.
Code generator even initialisation code make unprofessional and nobody at ST see it.
A lot of compile time functionality moved to runtime. Very bad.
2026-01-29 7:50 AM
@vybor wrote:It's awfully inconvenient to switch from IDE to Tool Configurtion time after time.
It's seems that decision makers far from development.
That's a separate discussion - please use this thread for it: IDE Version 2.0.0 - why remove MX ?
2026-01-29 11:38 AM
Decent code generator must generate something like this with minimal runtime overhead.
It has all the data to make work at compile time.
void
MX_GPIO_Init (void)
{
LL_GPIO_SetPinSpeed (LED_BLUE_GPIO_Port, LED_BLUE_Pin, LL_GPIO_SPEED_FREQ_LOW);
LL_GPIO_SetPinOutputType (LED_BLUE_GPIO_Port, LED_BLUE_Pin, LL_GPIO_OUTPUT_PUSHPULL);
LL_GPIO_SetPinPull (LED_BLUE_GPIO_Port, LED_BLUE_Pin, LL_GPIO_PULL_NO);
LL_GPIO_SetPinMode (LED_BLUE_GPIO_Port, LED_BLUE_Pin, LL_GPIO_MODE_OUTPUT);
LL_GPIO_SetPinSpeed (GPIOA, LL_GPIO_PIN_1, LL_GPIO_SPEED_FREQ_HIGH);
LL_GPIO_SetPinOutputType (GPIOA, LL_GPIO_PIN_1, LL_GPIO_OUTPUT_PUSHPULL);
LL_GPIO_SetPinPull (GPIOA, LL_GPIO_PIN_1, LL_GPIO_PULL_UP);
LL_GPIO_SetPinMode (GPIOA, LL_GPIO_PIN_1, LL_GPIO_MODE_OUTPUT);
}Following functionallity from runtime is removed:
1. Creation of LL_GPIO_InitTypeDef
2. Copy from compile time constants to the struct fields
3. Copy from the struct fields to function parameters
4. Execution of LL_GPIO_Init function with bunch of code
5. Execution of asserts. At compile time can be much more robust checks than at rumtime.
In such obvious case ST code genertor generate bloated code with runtime overhead for years.