2014-09-17 4 views
14

저는 C++ 초보자이며 언어의 기초를 배우고 있습니다. 이 컴파일러에 대한 나의 책에서 주제이며, 내 문제는 내가 텍스트가 말하고자하는 것을 이해 할 수 없다는 것입니다 : 당신이 파일에 소스 코드를 변환 할 필요가 있으므로코드 개체와 실행 파일의 차이점

C++ 컴파일 된 언어입니다 컴퓨터가 실행될 수 있습니다. 이 파일은 컴파일러에 의해 생성되며 객체 코드 (.obj)라고 불립니다. 그러나 과 같은 프로그램은 우리가 작성한 부분과 C++ 라이브러리의 부분으로 구성됩니다. 링커는 프로그램의이 두 부분을 연결하고 은 실행 파일 (.exe)을 생성합니다.

왜 내 책은이 EXE 접미사 하나라고 말할 다음 컴퓨터에 의해 실행되는 파일이 OBJ 접미사 (오브젝트 코드)와 하나라는 것을 말해 무엇입니까?

+3

컴퓨터에서 (실행), 다음 링커는 그 객체는 실행 파일을 생성, 파일을 함께 연결합니다. – 0x499602D2

+1

당신의 책의 비유와 함께,'printf ("Hello, world! \ n");'는 "우리가 쓰는"부분이므로 객체 코드는'printf'를 호출하는 명령을 가질 수 있습니다. 표준 라이브러리는 실제로'printf'를 구현하는 부분입니다 (어떻게 인쇄 할 예정입니까 ??). 그것이 차이점입니다. 물론 일반적으로 C++에서는'cout << "Hello, world! \ n"; "라고 쓰지만 첫 번째 프로그램은 아이디어가 같습니다. – Brandin

답변

27

오브젝트 파일은 2 진 기계 언어로 소스 컴파일되었지만 해결되지 않은 외부 참조 (예 : printf)를 포함합니다. 다른 오브젝트 파일, 제 3 자 라이브러리 및 거의 항상 C/C++ 런타임 라이브러리와 링크해야 할 수도 있습니다.

유닉스에서 객체와 exe 파일은 모두 동일한 COFF 형식입니다. 유일한 차이점은 객체 파일에는 해결되지 않은 외부 참조가 있지만 a.out 파일에는 해석되지 않는 것입니다.

+9

아니요, COFF는 대부분의 Unix에서 더 이상 사용되지 않습니다. 그들은 (리눅스로) ELF를 사용합니다! –

+3

참 고맙습니다. 다른 약어, 질문의 맥락에서 같은 차이! – ArunasR

8

C++ 사양은 영어로 된 기술 문서입니다. C++11n3337 내부를보고 (또는 페이퍼 백 ISO 표준을 구입하기 위해 많은 돈을 씁니다). 이론 상으로는 C++ 프로그램을 실행하는 데 컴퓨터가 필요하지 않습니다 (인간 노예를 많이 사용할 수는 있지만 비 윤리적이며 비효율적이며 신뢰할 수 없습니다).

당신은 interpreter 아닌 compiler (예 : Ch by SoftIntegration) 당신은 (나는 모든 학생에게 일을 권장) 노트북에 리눅스를 설치하는 경우에 당신이 할 수

여러 free software C++ 컴파일러 인 C++ 구현을 가질 수있다 , 특히 GCCClang/LLVM (각각 g++clang 명령 사용). 소스 파일은 .cc 또는 .cxx 또는 .cpp 또는 심지어 .C (선호하는 .cc)의 접미어가 붙어 있으며 다른 접미사 파일을 C++ 소스 파일로 처리하도록 컴파일러에 요청할 수 있습니다 (단, 이는 일반적인 것이 아닙니다). 그런 다음 object files (접미어 .o)과 executables은 모두 ELF 형식을 공유합니다.

종래, 실행 파일 접미사가없는 (- -, ld 년 - linker 등 ... g++cc1plus 년 - 컴파일러 proper-, as 년 - assembler 같은 다른 프로세스를 시작 제외하고는 많이 안하고, 바이너리 실행 파일입니다 예를 들어) 모든 경우에

나는 강력하게 추천 :

  • 가 컴파일하는 동안 모든 경고와 디버그 정보를 사용하려면 (예 : g++ -Wall -g를 사용 ....더 경고를 얻지까지)
  • 이 소스 코드를 개선하기 위해
  • 디버거 (gdb)
  • 명령 줄에서 프로그램을 구축 할 수 있도록 사용 방법을
  • 버전 제어 시스템을 사용하는 방법을 배우게하기 여러 소스 파일에서 프로그램을 작성하면 같은 git
  • emacs, gedit, geany 또는 gvim
  • 같은 좋은 편집기를 사용하여,,469을 같은 빌더를 사용하는 방법 그들이 개선 것이기 때문에
  • 9,953,210은 다른 프로그래밍 언어 (OCaml의, 계획, 하스켈, 프롤로그, 스칼라을, ....) 배우고 C++ 11 (또는 아마도 C++14)보다는 이전의 C++ 표준
  • 을 배울 수 당신의 생각과 코딩 방법을 C++에서
  • C 언어로 코딩 된 여러 무료 소프트웨어의 소스 코드를 공부하려면
  • 사용중인 모든 기능의 문서를 읽으십시오. cppreference 또는 man pages (Linux의 경우)
  • undefined behavior이 무엇인지 이해해야합니다 (프로그램이 올바르게 작동하지 않는 경우에도 문제가 해결됨).

구체적으로, 리눅스에 당신이 등 (gedit hello.cc 같은 명령으로) gedit 또는 emacs와 안녕하세요 프로그램 (파일 hello.cc)을 편집 할 수 ..., gdb ./hello을 사용 g++ -Wall -g hello.cc -o hello 명령, 디버그를 사용하여 컴파일, 반복 (버전 관리에 git 명령을 사용하는 것을 잊지 마십시오).

때때로 일부 C++ 코드를 생성하는 것이 좋습니다. 일부 쉘, 파이썬 또는 awk 스크립트 (또는 C++ 코드를 생성하는 C++로 코드화 된 사용자 자신의 프로그램으로도 가능)가 있습니다.

또한 IDE이 아니며 컴파일러는입니다 (그러나 컴파일러는 실행됩니다).

+0

Clang은 특히 경고와 오류를보고하는 데 능숙하며 GCC보다 더 잘 수행합니다. 또한 새로운 표준을보다 빨리 지원합니다. 장애물이 적기 때문에 OP를 사용하는 것이 좋습니다. – Kalrish

+0

정확히 맞지 않음 : 최근 GCC 4.9가 경고 및 C++ 지원과 관련하여 많은 개선 11 –

+0

GCC가 개선되었지만 진단이 아직 명확하지 않으며 C++ 14도 지원하지 않습니다 (Clang, as 3.5의 경우). 생성 된 (기계) 코드 품질은 다른 이야기이지만 :). – Kalrish

3

다양한 소프트웨어 개발 도구와 함께 컴퓨터 프로그래밍에 사용되는 언어는 수년에 걸쳐 발전해 왔습니다.

첫 번째 컴퓨터는 콘솔에서 스위치로 입력 한 숫자로 프로그래밍되었습니다.

사람들은 소프트웨어를보다 쉽고 빠르게 만드는 데 사용할 수있는 언어와 소프트웨어를 개발하기 시작했습니다. 첫 번째 주요 개발은 소스 코드의 각 라인이 컴퓨터 프로그램에 의해 기계어 명령으로 변환되는 어셈블러 언어를 작성하는 것이 었습니다. 이와 함께 링커 (기계 코드 조각을 더 큰 조각으로 연결 함)가 개발되었습니다. 어셈블러는 어셈블리 언어 용으로 설계된 C/C++ 프리 프로세서와 비슷한 매크로 또는 선처리 기능을 추가하여 향상되었습니다.

그런 다음 사람들은 어셈블러가 아닌 언어로 작성된 사람들처럼 보이는 프로그래밍 언어를 만들었습니다 (예 : FORTRAN 및 COBOL 및 ALGOL). 이러한 언어는 읽기가 쉬우 며 한 줄의 소스가 여러 기계 명령어로 변환 될 수 있으므로 어셈블러보다는 이러한 언어로 컴퓨터 프로그램을 작성하는 것이 더 생산적이었습니다.

C 프로그래밍 언어는 FORTRAN과 같은 초기 프로그래밍 언어에서 얻은 교훈을 사용하여 나중에 구체화되었습니다. 그리고 C는 이미 존재하던 링커 같은 이미 존재했던 것과 동일한 소프트웨어 개발 도구를 사용했습니다. C++은 객체 지향적 인 기능을 도입 한 C의 세련미부터 시작하여 나중에 C++가 발명되었습니다. 실제로 첫 번째 C++ 컴파일러는 C++ 소스 코드를 C 소스 코드로 변환 한 C++ 변환기였습니다.이 소스 코드는 C 컴파일러로 컴파일되었습니다. 그러나 현대의 C++은 C++ 표준의 모든 기능을 템플릿, 람다 및 C++ 11 이상의 모든 기타 기능과 함께 제공하기 위해 코드를 직접 작성합니다.

C 또는 C++ 소스 파일에서 응용 프로그램을 만드는 기본 단계는 다음과 같습니다. (1) 소스 파일이 생성됩니다 (2) 소스 파일이 컴파일됩니다 (실제로는 전처리 기와 컴파일), (3) C/C++ 컴파일러에서 만든 개체 파일을 연결하여 .exe

컴퓨터 프로그램의 한 버전을 다른 버전으로 변환하는 단계가 있습니다. C++ 소스는 오브젝트 파일을 생성하도록 컴파일됩니다. 그런 다음 오브젝트 파일을 링크하여 실행 파일을 생성합니다.

프로그램을 실행하면 실행 파일이 실행됩니다. 실행 파일에는 여러 종류의 정보가 들어 있습니다. 첫 번째는 C++ 소스 코드를 컴파일 한 결과 인 기계 명령어입니다. 다른 하나는 로더가 실행 파일을 메모리로로드하는 방법을 알기 위해 사용하는 정보입니다.

예전에는 모든 라이브러리와 오브젝트 파일이 실행 파일에 링크되었으며 실행 파일은 로더에 의해로드되었고 로더는 매우 간단했습니다.

그런 다음 사람들은 공유 라이브러리와 동적 링크 라이브러리를 고안했으며 이로 인해 더 복잡한 로더가 필요했습니다. 로더는 실행 파일을 메모리에로드하여 실행을 시작할 수있을뿐만 아니라 로더는 필요한 공유 라이브러리 또는 동적 링크 라이브러리도 찾아로드해야합니다. 또한 로더는 추가 구성 요소 인 공유 라이브러리를 일정량 연결해야하므로 로더가 이전보다 훨씬 많은 작업을 수행합니다.

+0

이것은 훌륭한 대답입니다. John R. Levine이 "Linkers and Loaders"라는 책을 추가로 추천합니다. –

2

(오브젝트 파일 내에서) 오브젝트 코드 : 링커에 대한 입력으로 의도 된 컴파일러로부터의 출력 (링커가 실행 가능 코드를 생성하기 위해).

실행 : 준비 프로그램이 실행되는 프로그램의 소스 파일을 오브젝트 파일로 컴파일됩니다