ARM Cortex-M7项目:GCC与G++编译C/C++代码的选型建议咨询
Great question—this is a super common scenario when transitioning to mixed C/C++ code in embedded systems, especially with low-level register-focused code. Let’s break down both approaches and which one makes more sense for your setup:
Option 1: Compile C code with GCC, C++ with G++, then link them
If your low-level register headers are pure C (no C++-specific syntax) and you don’t want to modify them right now, this approach works well. Here’s what to keep in mind:
- No changes to existing C headers: GCC will handle register macros,
volatilequalifiers, and raw memory accesses exactly as intended without any fuss. - Linkage is critical: When your C++ code includes those C headers, wrap the includes in
extern "C"blocks to prevent C++ name mangling from breaking symbol resolution at link time. For example:extern "C" { #include "cortex_m7_registers.h" // Your register header } - Makefile setup: You’ll need separate rules for C and C++ files. Use
$(CC)(pointing toarm-none-eabi-gcc) for.cfiles, and$(CXX)(pointing toarm-none-eabi-g++) for.cppfiles. Link with$(CXX)—it automatically handles both C and C++ symbols, plus any C++ standard library dependencies if you’re using them.
This is a solid quick fix if you want to get up and running fast without touching your existing C infrastructure.
Option 2: Modify headers to compile everything with G++
This is the more scalable long-term approach, especially if you plan to expand your C++ codebase. The main change is making your C headers C++-compatible:
- Add
extern "C"conditionals: Wrap your header contents in a check for the C++ compiler, so they work with both GCC and G++:#ifdef __cplusplus extern "C" { #endif // Your register macros, typedefs, and memory address declarations here #define GPIOA_BASE (0x40020000UL) typedef volatile uint32_t reg32_t; #ifdef __cplusplus } #endif - Fix C++ syntax strictness: C++ is pickier about certain things than C, like explicit type conversions. A raw pointer cast like
*(reg32_t*)GPIOA_BASEmight trigger a warning—you can update it to usereinterpret_cast(more C++-idiomatic) or keep the C-style cast and use compiler flags like-Wno-cast-qualif you prefer not to change the code. - Simpler Makefile: You can compile all
.cand.cppfiles witharm-none-eabi-g++and link with the same tool, eliminating separate rules for C and C++ targets.
Recommendation for your case
Since you mentioned your C code is currently just register headers (no function implementations), modifying the headers to be C++-compatible is the better choice. It’s a tiny change, keeps your build process clean, and avoids headaches later if you add C functions that need to be called from C++. Plus, you won’t have to juggle two different compilers in your Makefile, which reduces complexity.
Just make sure to test the modified headers with both GCC (if you ever need to compile pure C again) and G++ to ensure compatibility.
内容的提问来源于stack exchange,提问作者joe blogs

