![](/img/trans.png)
[英]G++ makes smaller binary than GCC after C++ compatibility changes, but slightly larger than the prior binary?
[英]The size of output binary is smaller by using gcc rather than g++
我正在將我的項目從 C 遷移到 C++,今天我注意到了一些奇怪的事情。 我有兩個幾乎相同的(唯一的區別是 extern 關鍵字 in.cpp)主文件(為編譯測試目的而創建)。 第一個是 main.c,第二個是 main.cpp。
您可以在下面找到這些文件的源代碼。 我使用的是libopencm3,它被編譯成static庫,然后它被鏈接到任何需要的地方。 那么問題是什么? 在我使用 main.c(使用 gcc)編譯我的項目的場景中,output 二進制文件比 output 生成的二進制文件(使用 g++c 編譯)小得多。 我無法弄清楚是什么導致了這個問題?
該代碼是為 STM32F1C8T6 目標編譯的。
//main.c
#include <libopencm3/stm32/rcc.h>
static void rcc_setup()
{
//Clock setup
rcc_clock_setup_in_hse_8mhz_out_72mhz();
//Peripherals clock
rcc_periph_clock_enable(RCC_GPIOA);
rcc_periph_clock_enable(RCC_GPIOB);
}
int main()
{
rcc_setup();
while(1)
{
}
}
//main.cpp
extern "C" {
#include <libopencm3/stm32/rcc.h>
}
static void rcc_setup()
{
//Clock setup
rcc_clock_setup_in_hse_8mhz_out_72mhz();
//Peripherals clock
rcc_periph_clock_enable(RCC_GPIOA);
rcc_periph_clock_enable(RCC_GPIOB);
}
int main()
{
rcc_setup();
while(1)
{
}
}
我的項目的結構基本上是這樣的:
- root
CMakeLists.txt
- lib
- libopencm3
- src
- app
CMakeLists.txt
- inc
- src
- main.c
- main.cpp
這是我的根 CMakeFile.txt。 我認為它是最重要的,因為它包含編譯標志等。其中還有一些其他的東西,比如端口目錄,port.cmake 等,但這些在這種情況下並不重要,所以請忽略它們。
cmake_minimum_required(VERSION 3.16)
project(stm32-template)
# COMPILER JUST TEMPORARY TODO: REMOVE!!!
set(CMAKE_ASM_COMPILER "/usr/bin/arm-none-eabi-gcc")
set(CMAKE_C_COMPILER "/usr/bin/arm-none-eabi-gcc")
set(CMAKE_CXX_COMPILER "/usr/bin/arm-none-eabi-g++")
# CMAKE MODULES
include(${CMAKE_ROOT}/Modules/ExternalProject.cmake)
# GENERAL PATHS
set(PORT_DIR ${PROJECT_SOURCE_DIR}/src/port/${PORT})
# PORT CONFIGURATIOM
include(${PORT_DIR}/port.cmake)
# COMPILER CONFIGURATION
set(COMPILER_CXX_FLAGS "-fno-use-cxa-atexit -Os")
set(COMPILER_FLAGS "-fdata-sections -ffunction-sections -O0 -DNDEBUG -Werror")
set(LINKER_FLAGS "-nostartfiles -specs=nano.specs -specs=nosys.specs --static -ggdb3 -Wl,--gc-sections -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group -Wl,-Map=output.map -T ${LD_SCRIPT}")
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_C_FLAGS "${COMPILER_FLAGS} ")
set(CMAKE_CXX_FLAGS "${COMPILER_CXX_FLAGS} ${COMPILER_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${LINKER_FLAGS}")
# LIBRARIES
set(LIBOPENCM3_PATH ${PROJECT_SOURCE_DIR}/lib/libopencm3)
set(LIBOPENCM3_INCLUDE ${LIBOPENCM3_PATH}/include)
set(LIBOPENCM3_BIN ${LIBOPENCM3_PATH}/lib/libopencm3_${MCU_FAMILY}.a)
ExternalProject_Add(libopencm3
SOURCE_DIR "${LIBOPENCM3_PATH}"
BUILD_IN_SOURCE true
DOWNLOAD_COMMAND ""
CONFIGURE_COMMAND ""
INSTALL_COMMAND ""
BUILD_COMMAND make
)
# ADD LIBRARY INCLUDES
include_directories(${LIBOPENCM3_INCLUDE})
# SUBDIRECTORIS
add_subdirectory(src)
# CUSTOM COMMANDS
add_custom_target(flash
COMMAND JLinkExe -device STM32F103C8 -If SWD -Speed 1000 -CommandFile tools/jlink/FlashCommand.jlink
COMMENT "asd"
#DEPENDS {EXE_NAME}
)
C++ 語言的運行時間比 C 語言大得多(因為異常、RTTI、 <iostream>
、 <thread>
等)。
當您靜態鏈接應用程序時,您會鏈接整個語言運行時,或者至少鏈接代碼中某處引用的那些部分,包括 static 的對象和您拉入的標頭中的線程本地存儲持續時間(例如 std::cout )。 大多數桌面應用程序看不到這一點,因為它往往在 DSO 中。
由於語言互操作,您會發現很多 C++ 運行時實際上在您的系統 libc 中。 這包括異常處理和展開。 如果您看到像 __cxa_* 和Unwind * 這樣的符號,那就是發生了什么。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.