예를 들어, 과거 의 SysInternals 도구 "FileMon"에는 소스 코드가 완전히 4,000 행 파일 인 커널 모드 드라이버가 있습니다. 최초의 핑 프로그램 (~ 2,000 LOC)도 마찬가지입니다.
예를 들어, 과거 의 SysInternals 도구 "FileMon"에는 소스 코드가 완전히 4,000 행 파일 인 커널 모드 드라이버가 있습니다. 최초의 핑 프로그램 (~ 2,000 LOC)도 마찬가지입니다.
답변:
여러 파일을 사용하려면 항상 추가 관리 오버 헤드가 필요합니다. 컴파일 및 링크 단계가 분리 된 빌드 스크립트 및 / 또는 makefile을 설정하고, 서로 다른 파일 간의 종속성이 올바르게 관리되는지 확인하고, 이메일 또는 다운로드를 통해 소스 코드를보다 쉽게 배포 할 수 있도록 "zip"스크립트를 작성해야합니다. 의 위에. 오늘날의 IDE는 일반적으로 많은 부담을 겪지 만, 첫 번째 핑 프로그램이 작성 될 당시에는 그러한 IDE를 사용할 수 없었습니다. 그리고 ~ 4000 LOC 정도로 작은 파일의 경우 여러 파일을 잘 관리하는 IDE가 없으면 언급 된 오버 헤드와 여러 파일 사용의 이점 사이의 균형을 통해 사람들이 단일 파일 접근 방식을 결정할 수 있습니다.
C는 모듈화에 좋지 않기 때문입니다. 더러워지고 (헤더 파일 및 #include, extern 함수, 링크 타임 오류 등) 더 많은 모듈을 가져올수록 더 까다로워집니다.
더 현대적인 언어는 C의 실수로부터 배웠기 때문에 부분적으로 더 나은 모듈화 기능을 가지고 있으며 코드베이스를 더 작고 간단한 단위로 쉽게 분류 할 수 있습니다. 그러나 C를 사용하면 너무 많은 코드로 간주되는 것을 단일 파일에 집중시키는 것을 의미하더라도 모든 문제를 피하거나 최소화하는 것이 좋습니다.
역사적 이유 외에도 최신 성능에 민감한 소프트웨어에서이를 사용해야하는 이유가 있습니다. 모든 코드가 하나의 컴파일 단위에 있으면 컴파일러는 전체 프로그램 최적화를 수행 할 수 있습니다. 별도의 컴파일 단위를 사용하면 컴파일러는 특정 방식 (예 : 특정 코드 인라인)으로 전체 프로그램을 최적화 할 수 없습니다.
링커는 컴파일러가 수행 할 수있는 작업 외에도 일부 최적화를 수행 할 수 있지만 전부는 아닙니다. 예를 들어, 최신 링커는 여러 객체 파일에서도 참조되지 않은 기능을 효과적으로 제거합니다. 그들은 다른 최적화를 수행 할 수 있지만 컴파일러가 함수 내에서 할 수있는 것과는 다릅니다.
단일 소스 코드 모듈의 잘 알려진 예는 SQLite입니다. 자세한 내용 은 SQLite Amalgamation 페이지 에서 확인할 수 있습니다 .
1. 요약
100 개가 넘는 별도의 소스 파일이 "sqlite3.c"라는 하나의 큰 C 코드 파일로 연결되고 "아말감 화"라고합니다. 통합에는 응용 프로그램에 SQLite를 포함시키는 데 필요한 모든 것이 포함됩니다. 합병 파일의 길이는 180,000 줄 이상이고 6MB 이상입니다.
SQLite의 모든 코드를 하나의 큰 파일로 결합하면 SQLite를보다 쉽게 배포 할 수 있습니다. 추적 할 파일은 하나뿐입니다. 또한 모든 코드가 단일 변환 단위로되어 있기 때문에 컴파일러는보다 나은 절차 간 최적화를 수행하여 기계 코드가 5 %에서 10 % 더 빠릅니다.
$(CC) $(CFLAGS) $(LDFLAGS) -o $(TARGET) $(CFILES)
모든 것을 단일 soudce 파일로 옮기는 것보다 빌드 스크립트를 변경하는 것이 훨씬 쉽습니다 . 프로덕션 대상에 대한 프로파일 링 및 디버깅을 해제하는 방법과 유사하게 변경되지 않은 소스 파일을 다시 컴파일하는 기존 빌드 스크립트의 대체 대상으로 전체 프로그램 컴파일을 수행 할 수도 있습니다. 모든 것이 하나의 큰 힙 소스에있는 경우 해당 옵션이 없습니다. 사람들이 익숙하지 않은 것은 아니지만 그것에 대해 번거로운 것은 없습니다.
다른 응답자가 언급 한 단순성 요소 외에도 많은 C 프로그램이 한 개인이 작성합니다.
개인 팀이있는 경우 코드 변경시 충돌이 발생하지 않도록 응용 프로그램을 여러 소스 파일로 분할하는 것이 바람직합니다. 특히 고급 프로그래머와 초보 프로그래머가 프로젝트에 참여하는 경우.
한 사람이 혼자서 일할 때는 문제가되지 않습니다.
개인적으로, 나는 기능에 따라 여러 파일을 습관적으로 사용합니다. 그러나 그것은 단지 나입니다.
C89에는 inline
기능이 없었기 때문 입니다. 즉, 파일을 함수로 나누면 스택에서 값을 푸시하고 뛰어 넘는 오버 헤드가 발생했습니다. 이것은 1 개의 큰 스위치 문 (이벤트 루프)에서 코드를 구현하는 것보다 약간의 오버 헤드를 추가했습니다. 그러나 이벤트 루프는 모듈화 된 솔루션보다 항상 효율적으로 (또는 정확하게) 구현하기가 훨씬 어렵습니다. 따라서 대규모 프로젝트의 경우 사람들은 여전히 모듈화를 선택하지 않습니다. 그러나 사전에 설계를 고려하고 1 개의 스위치 문으로 상태를 제어 할 수 있었을 때,이를 선택했습니다.
현재 C에서도 C 함수에서도 인라인 될 수 있기 때문에 모듈화를 위해 성능을 희생 할 필요가 없습니다.
inline
C89 컴파일러에 키워드 가 없기 때문에 인라인 할 수 없기 때문에 하나의 거대한 함수로 모든 것을 작성 해야하는 이유가 잘못 되었다는 것입니다. inline
성능 최적화로 사용해서는 안됩니다 . 컴파일러는 일반적으로 사용자보다 더 잘 알고 있습니다 (키워드도 무시할 수 있음).
inline
키워드는 인라인 최적화를 수행할지 여부의 문제보다 더 중요 링커 관련 의미를 가지고 있지만, 일부 구현에 라이닝 제어와 같은 일들이 때로는 매우 중요 할 수있는 다른 지침을 가지고있다. 경우에 따라 함수가 너무 커서 인라인 할 가치가없는 것처럼 보일 수 있지만, 일정한 폴딩으로 인해 크기와 실행 시간이 거의 줄어들지 않을 수 있습니다.
이것은 아직 진화론의 한 예입니다.
어두운 시절에는 단일 FILE을 컴파일하는 데 몇 분이 걸릴 수 있습니다. 프로그램이 모듈화 된 경우 필요한 헤더 파일을 포함하면 (사전 컴파일 된 헤더 옵션 없음) 속도 저하의 중요한 추가 원인이됩니다. 또한 컴파일러는 자동 스왑 파일의 이점없이 디스크 자체에 일부 정보를 유지하도록 선택 / 필요할 수 있습니다.
이러한 환경 적 요인으로 인해 지속적인 개발 관행이 이어지고 시간이 지남에 따라 천천히 적응해 왔습니다.
당시 단일 파일을 사용함으로써 얻는 이득은 HDD 대신 SSD를 사용하여 얻는 것과 비슷합니다.