Day2
cpp 하나마다 obj 파일 컴파일됨
#include
헤더 파일을 포함시키는 구문 include를 많이 쓸 수록 헤더 파일을 불러오기 때문에 느려진다
main함수
return 0을 안적어줘도 동작하는 이유는 컴파일러가 몰래 해주기 때문이다
cpp build process
- 전처리
- 주석 등 컴파일하는데 필요한/필요없는 코드 제거
- 컴파일
- cpp 파일 하나만 바라봄(다른 파일과의 관계는 관심없음)
- 문법적으로 명세만 잘 지켜져있으면 함수 내용이 파일에 없더라도 넘김. 실제 코드가 없으면 링커오류(LNK****)
- 어셈블러
- 링커
- 파일 단위의 링킹은 무식한 방법으로 코드 일일이 뒤져서 다 링킹해줌(cpp 컴파일이 느린 이유)
- 명시적으로 링크를 안걸어줘도 인텔리센스가 알아서 찾아줌(Main.cpp에 Log 명세만 적어줘도 Log.cpp를 링킹해줌)
#include <iostream>#include "Log.h" // void Log(const char* message);로 치환됨// F12. Ctrl + - : 참조/돌아가기// Ctrl + 방향키 좌우 : // Home + End + Shift : // Alt + Shit + 방향키 : 여러 줄 동시 선택int main(){ Log("Hello World"); //std::cout << "Hello World\n"; // 프로그램 바로 종료되지 않게 하는 코드 std::cin.get();}header
컴파일 대상이 아니라 컴파일 결과물에 obj 파일 말고는 없음
C#
이진코드를 메타파일로 런타임에 메타파일을 가지고 바이너리 코드로 만들어 콜스택에 올림 생산성 측면에선 C#, 자바가 C++보다 좋으나 실행 속도에선 반대(위 과정 때문에)
dll
런타임에 불러오는 동적 링크 라이브러리. 반대는 STL(Static Library): 컴파일 시점에 코드가 실행 코드 안에 들어가있음
| 구분 | DLL (동적) | 정적 라이브러리 |
|---|---|---|
| 링크 시점 | 실행 시 (Runtime) | 컴파일/링크 시 |
| 파일 형태 | .dll | .lib, .a |
| 메모리 사용 | 공유 가능 | 프로그램별 개별 |
| 배포 | DLL 포함 필요 | exe 하나로 가능 |
| 업데이트 | DLL만 교체 | 전체 재빌드 |
| 안정성 | DLL 지옥(dll간 버전 충돌 혹은 누락) | 안정적 |
함수 포인터
함수는 주소로 치환돼 쓰인다 보통 내가 아닌 다른 주체가 함수를 실행해줘야할 때(=callback) 함수 포인터를 쓴다 e.g. 마우스 클릭 이벤트가 일어났을 때 A함수를 콜백해줘야하는 상황
delegate
“함수(메서드에 대한 참조를 담는 타입)”, 즉 함수를 변수처럼 전달하기 위한 타입이다.
일반 함수에도 가능하고 클래스 인스턴스의 함수에도 가능하다 다만 인스턴스의 메서드에도 똑같이 해주려면 인스턴스의 정보를 알아야 함 그래서 C#은 일반 함수 자체를 delegate 지원하지 않게 원천차단함 = 맨처음 C#을 시작할 때 class가 튀어나오는 이유
Pointer
단지 메모리 주소를 저장하는 변수
역참조 문법: *a = 10;
메모리
함수의 매개변수 자체도 메모리 할당됨
void foo(int a, int b) { // a, b는 스택 프레임에 할당된다 // 함수 종료 시 자동으로 해제됨}L-value, R-value, Value Category
## 레지스터, 스택 프레임?
스택 프레임
콜 스택 안에 쌓이는 개별 함수 호출 하나에 해당하는 메모리 블록
해당 함수가 사용하는
매개변수지역 변수반환 주소저장된 레지스터 값~~을 포함함
[ 콜 스택 ] ├─ main() 스택 프레임 │ ├─ 지역 변수 │ ├─ 매개변수 │ └─ 반환 주소 ├─ foo() 스택 프레임 │ ├─ 지역 변수 │ └─ 매개변수 └─ bar() 스택 프레임 ← 현재 실행 중스택과 힙은 day4에서 배울 예정