Adaid's Workroom
[C++] Google C++ 코딩 스타일 정리(작성중) 본문
자료: 원문링크, 번역링크
(번역본은 원문에서 빠진 내용도 약간 있으며 오역이 다소 있는듯)
(원문 내용을 최대한 살려서 번역하면서 변역본도 참고하며 작성)
헤더파일
모든 .cc 파일은 수반된 .h 파일을 가져야 한다(예외: 유닛테스트, main만 있는 작은 .cc 파일).
헤더 파일을 바르게 사용함으로써 코드의 가독성, 크기, 성능을 향상시킬 수 있다.
독립적 해더
헤더파일은 독립적이어야 하며(=자체적으로 컴파일되어야 함)
(1) #define 가드
모든 헤더 파일은 여러번 포함되지 않기 위해 #define 가드를 사용해야 한다.
심볼 이름의 포맷은 <PROJECT>_<PATH>_<FILE>_H_
으로 한다.
심볼 이름이 겹치지 않기 위해 프로젝트 파일 경로에 기반한다.
(ex) foo 프로젝트의 foo/src/bar/baz.h 파일의 가드
#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_
...
#endif FOO_BAR_BAZ_H_
(2) 전방 선언
전방 선언은 클래스, 함수, 템플릿 등을 수반되는 정의 없이 선언하는 것이다.
장점
- 컴파일 시간을 절약할 수 있다.
#include는 컴파일러가 더 많은 파일을 열고 더 많은 입력을 처리하기 때문
- 불필요한 재컴파일을 줄일 수 있다.
#include는 헤더에서 관계 없는 변경사항이 있을 때 코드를 더 자주 재컴파일 하도록 하기 때문.
단점
- 헤더가 변경되었을 때 필요한 재컴파일을 건너뛰게 하여, 종속성을 숨길 수 있다.
- 라이브러리에 대한 후속 변경으로 인해 전방 선언이 깨질 수 있다.
전방 선언은 헤더 소유자가 API에 대해 달리 호환되는 변경
(매개 변수 유형 확장, 디폴트 값이 있는 템플릿 매개 변수 추가, 새로운 네임스페이스로 이동 등)
을 하지 못하게 할 수 있다.
- std:: 네임스페이스의 기호를 전방 선언하는 것은 정의되지 않은 동작(UB)이 발생한다.
- 전방 선언과 전체 #include 중 어떤 것이 필요할 지 결정하는 것이 어려울 수 있다.
#include를 전방 선언으로 교체하는 것은 코드의 의미를 조용히 바꿀수도 있다.
(ex)
// b.h:
struct B {};
struct D : B {};
// good_user.cc:
#include "b.h"
void f(B*);
void f(void*);
void test(D* x) { f(x); } //calls f(B*)
만약 #include가 B와 D의 전방 선언으로 교체된다면 test()는 f(void*)를 호출할 것이다.
- 헤더에서 여러 기호를 전방 선언하는 것은 단순히 헤더를 #include하는 것보다 장황해질 수 있다.
(3) 인라인 함수
함수가 10줄 이하일때만 함수를 인라인으로 정의하라.
정의
컴파일러가 일반적인 함수 함수 호출 매커니즘으로 호출하는 대신 인라인으로 확장할 수 있도록 함수를 선언할 수 있다.
장점
인라인 함수가 작을수록 오브젝트 코드를 더 효율적으로 생성할 수 있다.
편할대로 접근자, 변경자, 다른 작은 함수, 성능에 결정적인 함수들을 인라인 해도 좋다.
단점
인라인의 남용은 프로그램을 실제로 더 느리게 만들 수 있다.
함수를 인라인하는 것은, 그 함수 크기에 따라 코드 크기가 커지거나 작아지게 할 수 있다.
아주 작은 접근자 함수를 인라인한느 것은 일반적으로 코드 크기를 작게 하지만,
반면 매우 큰 함수를 인라인하는 것은 코드 크기를 매우 크게 할 수 있다.
현대의 프로세서들은 인스트럭션 캐쉬를 더 잘 활용하기 때문에, 작은 코드는 일반적으로 더 빨리 돈다.
결론
- 괜찮은 경험 법칙은 코드가 10줄 이상인 함수를 인라인하지 않는 것이다.
소멸자를 주의하라.
소멸자는 멤버/베이스(상위 클래스) 소멸자를 함축하고 있기 때문에 종종 보이는 것보다 길어질 수 있다!
- 또 다른 유용한 경험법칙이 있다.
반복문이나 switch문이 있는 함수를 인라인하는 것은 보통 효과적이지 않다.
(보통의 경우 절대 실행되지 않는 반복문이나 switch문이 있는 경우를 제외하고)
- 함수가 인라인으로 선언되었다고 해서 항상 인라인되는 것은 아님을 알아야 한다.
예를 들어, virtual 함수나 재귀 함수는 보통 인라인되지 않는다.
일반적으로 재귀 함수는 인라인되면 안된다.
가상 함수를 인라인하는 주된 이유는 클래스 안에 정의를 넣기 위해서이며, 이는 편의성 때문이거나 그것이 하는 일을 문서화하기 위해서 이다 (ex. 접근자와 변경자를 위해).
(4) inl.h 파일
필요한 경우 복잡한 인라인 함수들을 정의하기 위해 -ini.h 접미어가 붙은 파일 이름을 사용할 수 있다.
'전공 공부 > 언어' 카테고리의 다른 글
[C++] OOP in C++ (4) (진행중) (0) | 2018.06.23 |
---|---|
[C++] OOP in C++ (3) (0) | 2018.06.23 |
[C++] OOP in C++ (1) (0) | 2018.06.21 |
[C++] C에서 C++로 (0) | 2018.06.21 |