Programming

C ++ 초기 할당이 C보다 훨씬 큰 이유는 무엇입니까?

procodes 2020. 6. 24. 21:06
반응형

C ++ 초기 할당이 C보다 훨씬 큰 이유는 무엇입니까?


동일한 코드를 사용하는 경우 컴파일러를 C 컴파일러에서 C ++ 컴파일러로 변경하면 할당되는 메모리 양이 변경됩니다. 왜 이것이 더 많은지 잘 모르겠습니다. 지금까지 내가 얻은 최고의 응답은 "아마도 I / O 스트림"인데, 이는 매우 설명 적이 지 않으며 C ++의 "사용하지 않는 것에 대해 비용을 지불하지 않는다"는 점에 대해 궁금해합니다.

Clang 및 GCC 컴파일러 버전 7.0.1-8 및 8.3.0-6을 각각 사용하고 있습니다. 내 시스템은 최신 데비안 10 (버스터)에서 실행되고 있습니다. 벤치 마크는 Valgrind Massif를 통해 이루어집니다.

#include <stdio.h>

int main() {
    printf("Hello, world!\n");
    return 0;
}

사용 된 코드는 변경되지 않지만 C 또는 C ++로 컴파일하든 Valgrind 벤치 마크의 결과가 변경됩니다. 그러나 값은 컴파일러에서 일관성을 유지합니다. 프로그램의 런타임 할당 (피크)은 다음과 같습니다.

  • GCC (C) : 1,032 바이트 (1KB)
  • G ++ (C ++) : 73,744 바이트, (~ 74KB)
  • 클랑 (C) : 1,032 바이트 (1KB)
  • Clang ++ (C ++) : 73,744 바이트 (~ 74KB)

컴파일을 위해 다음 명령을 사용합니다.

clang -O3 -o c-clang ./main.c
gcc -O3 -o c-gcc ./main.c
clang++ -O3 -o cpp-clang ./main.cpp
g++ -O3 -o cpp-gcc ./main.cpp

Valgrind의 경우 valgrind --tool=massif --massif-out-file=m_compiler_lang ./compiler-lang각 컴파일러와 언어를 실행 한 다음 ms_print피크를 표시했습니다.

내가 여기서 잘못하고 있습니까?


힙 사용법은 C ++ 표준 라이브러리에서 가져옵니다. 시작시 내부 라이브러리 사용을위한 메모리를 할당합니다. 연결하지 않으면 C와 C ++ 버전간에 차이가 없습니다. GCC 및 Clang을 사용하면 다음을 사용하여 파일을 컴파일 할 수 있습니다.

g ++ -Wl,-필요에 따라 main.cpp

이렇게하면 링커가 사용되지 않은 라이브러리에 연결하지 않도록 지시합니다. 예제 코드에서 C ++ 라이브러리는 사용되지 않으므로 C ++ 표준 라이브러리와 링크하면 안됩니다.

C 파일로이를 테스트 할 수도 있습니다. 다음과 같이 컴파일하면 :

gcc main.c -lstdc ++

C 프로그램을 빌드했지만 힙 사용량이 다시 나타납니다.

힙 사용은 분명히 사용중인 특정 C ++ 라이브러리 구현에 달려 있습니다. 귀하의 경우에는 이것이 GNU C ++ 라이브러리 인 libstdc ++ 입니다. 다른 구현은 동일한 양의 메모리를 할당하지 않거나 전혀 메모리를 할당하지 않을 수 있습니다 (적어도 시작 하지는 않습니다). 예를 들어 LLVM C ++ 라이브러리 ( libc ++ )는 적어도 Linux에서 시작시 힙 할당을 수행하지 않습니다. 기계:

clang ++ -stdlib = libc ++ main.cpp

힙 사용은 전혀 링크하지 않는 것과 같습니다.

컴파일이 실패하면 libc ++가 설치되지 않은 것입니다. 패키지 이름은 일반적으로 "libc ++"또는 "libcxx"를 포함합니다.


GCC 나 Clang은 모두 컴파일러가 아니며 실제로 툴체인 드라이버 프로그램입니다. 즉, 컴파일러, 어셈블러 및 링커를 호출합니다.

C 또는 C ++ 컴파일러로 코드를 컴파일하면 동일한 어셈블리가 생성됩니다. 어셈블러는 동일한 객체를 생성합니다. 차이점은 툴체인 드라이버가 서로 다른 두 가지 언어에 대해 링커에 다른 입력을 제공한다는 것입니다. 다른 시작 (C ++에는 네임 스페이스 수준에서 정적 또는 스레드 로컬 저장 기간이있는 객체의 생성자와 소멸자를 실행하기위한 코드가 필요하며 스택을위한 인프라가 필요함) 예를 들어 예외 처리 중 해제를 지원하는 프레임, C ++ 표준 라이브러리 (네임 스페이스 레벨에서 정적 스토리지 기간의 오브젝트도 포함) 및 추가 런타임 라이브러리 (예 : 스택 해제 인프라가있는 libgcc).

요컨대, 풋 프린트를 증가시키는 컴파일러는 아니며 C ++ 언어를 선택하여 사용하기로 선택한 것들을 연결합니다.

C ++에 "사용하는만큼만 지불"이라는 철학이 있지만, 언어를 사용하면 비용을 지불하는 것이 사실입니다. 언어의 일부 (RTTI, 예외 처리)를 비활성화 할 수 있지만 더 이상 C ++을 사용하지 않습니다. 다른 답변에서 언급했듯이 표준 라이브러리를 전혀 사용하지 않으면 드라이버가 필요에 따라 (--Wl,-필요에 따라) 생략하도록 지시 할 수 있지만 기능을 사용하지 않을 경우 C ++ 또는 라이브러리에서 왜 C ++을 프로그래밍 언어로 선택합니까?

참고 URL : https://stackoverflow.com/questions/56692117/why-is-c-initial-allocation-so-much-larger-than-cs

반응형