
Project3. Virtual Memory에서 mmap을 구현하던 중 헤더 참조의 문제로 추정되는 에러가 발생했습니다.
filed 'spt' has incomplete type

Conflicting type for 'lazy_load_segment'

헤더를 추가하거나 코드의 위치를 변경하는 기존의 방식으로 해결할 수 없었습니다.


gcc 컴파일링 과정
1. page_cache.c의 3번째 줄의vm.h
2. vm.h의 32번째 줄의 file.h 참조
3. file.h의 5번째 줄의 process.h 참조
4. process.h의 5번째 줄의 thread.h 참조
5. thread.h에 있는spt참조 중 에러 발생(spt 구조체는vm.h에 선언)

1.
vm.h에서 spt 구조체는완전하고, vm.h를thread.h에 포함(include)했음에도 컴파일러가 불완전한 타입으로 인식하는 문제.
(이게 주된 원인이라 생각하여 코드를 추가하는 데에 집중했음)// vm.h struct supplemental_page_table { ... }// thread.h #ifdef VM #include "vm/vm.h" ... struct thread { ... struct supplemental_page_table spt;완전한 타입 : 해당 컴파일 시점에서 그 타입의 구현(Implement) 정보(enum, struct, union 등..)를 모두 알고 있는 타입
2.
page_cache.c는 Project.4에 사용되는 코드임에도 현재(VM)에 영향을 미치는 문제.



해당 답변을 통해
컴파일 과정,순환 참조,헤더 중복에 대해서 공부하다#ifndef와#pragma once에 대해 알게 됨

헤더 파일을 포함하면 헤더 파일이 필요한 각 소스 파일에 헤더 파일을 복사하는 것과 동일한 결과가 생성됩니다. - gcc.gnu
// header.h char *test (void);// program.c #include "header.h" int main (void) { puts (test ()); }
컴파일러는 program.c를 읽을 때와 동일한 token stream을 보게 됩니다.
// program.c char *test (void); int main (void) { puts (test ()); }
이러한 헤더의 컴파일은 PintOS와 같이 코드가 길어지고 구조가 복잡해질 때, 컴파일러가 헤더를 참조하는 과정에서 문제가 생길 수 있습니다.


순환 참조란 적게는 두 클래스가 서로를 참조하는 경우를 뜻합니다. 이 경우, 소스 코드에 클래스를 선언하고 있는 헤더를 include하여 해결합니다.
그러나 아래와 같이 여러 헤더가 순환 참조되는 경우도 발생할 수 있습니다.


또한 분할 컴파일을 하다보면 사용자가 정의한
헤더 파일이 중복되는 경우가 발생할 수 있습니다. 헤더 파일의 중복은 헤더 파일 안에 정의한 것이 2번 중복 정의되어 에러를 발생시킵니다.


- 가장 좋은 방법은 헤더들이 단방향으로 참조하도록 설계하는 것입니다.
- 아래와 같이 인터페이스를 추가하여 의존 관계를 역전시켜 헤더간의 의존 문제를 해결하는 방법도 있습니다.

#ifndef HEADER_H #define HEADER_H // 내용 #endif
- 헤더 파일을 처음 include할 때는 HEADER_H가 정의되어 있지 않습니다. 그때만 HEADER_H를 정의하고 헤더 파일의 내용들도 컴파일하여 중복을 피하는 방법입니다.
쉽게 말하자면if(!userprog/syscall.h) { 내용 }라고 볼 수 있습니다.
#pragma once도 include guard로서 위 코드와 동일한 역할로 사용됩니다. 함께 사용될 수도 있습니다.'#pragma' 지시어는 언어 자체에서 전달되는 것 외에 컴파일러에 추가 정보를 제공하기 위해 C 표준에서 지정한 방법입니다. -gcc.gnu

- page_cache.c는 Project.4에 사용되는 코드임에도 현재(VM)에 영향을 미친다. => page_cache.c를
#ifndef EFILESYS로 예외처리
- vm.h에서 spt 구조체는 완전하고, vm.h를 thread.h에 포함(include)했음에도 컴파일러가 불완전한 타입으로 인식한다.
=> 불필요한 process.h의 포함을 제거하여 및 단방향 참조로 코드 리팩토링



- 소스 코드에는 필요한 헤더만, 의존성을 고려해서 설계하자.
- 자신의 코드를 볼 때 시야가 좁아진다. 문제를 해결하는 시간이 일정 시간을 넘기면 주변 사람들에게 도움을 청하자.
- "순환 참조"라는 개념을 알기 전까지 문제를 전혀 인식하지 못 했다. 문제가 발생하면 해당 문제에 대해서 공부해야 한다.
- 트러블 슈팅하며 시도했던 방법들을 체계적으로 관리해야 한다. 같은 시도를 여러번 반복했다.
- "STUDY HARD, BE PATIENT, STEP BY STEP" -리처드 파인만
- 이러한 과정에서 극기(克己)가 중요하고, 내게 필요하다.

내 3일간의 피, 땀, 눈물..