개발시 프로그램 성능이나 개발시간 뿐 아니라 코드를 일관된 스타일로 잘 작성하는 것도 매우 중요하다. 본 포스팅에서는 C++ 코딩 스타일에 대해 다룬다.
• Part 1: Style
스타일 가이드라인은 생각보다 엄격하지 않다. 중요한 것은 적절한 공백과 일관된 스타일을 유지하여 이해하기 쉬운 코드를 짜는 것이다.
명시적이고 일관적인 네이밍
1. CamelCase
2. snake_case
이 둘은 가장 일반적으로 많이 사용되는 네이밍 스타일이다. 네이밍 스타일 뿐만 아니라 선택 단어 역시도, 선언되는 변수/함수의 기능을 명확하게 잘 드러낼 수 있도록 하자.
일반적인 C++ 네이밍 컨벤션
1. 타입의 첫 글자는 대문자로 한다 : MyClass
2. 함수와 변수의 첫 글자는 소문자로 한다 : myMethod
3. 상수 값은 모두 대문자로 한다 : const int PI = 3.14159265358979323;
C++ 파일과 C 파일 구분하기
- C++ 소스의 확장자는 .cpp나 .cc를 사용한다(.c가 아닌). C++ 헤더도 마찬가지로 .hpp를 사용한다(.h가 아닌).
nullptr 사용하기
- C++11에서는 널 포인터 값을 나타내는 nullptr을 지원한다. 0이나 NULL대신 nullptr을 사용하도록 하자.
헤더 파일에 using 키워드 사용하지 않기
- 이로 인해 사용중인 네임 스페이스가 헤더 파일의 네임스페이스에 포함될 수 있기 때문에
헤더 가드 포함시키기
- 헤더 파일에 동일한 헤더를 여러번 포함하거나 다른 프로젝트의 다른 헤더와 충돌하는 것을 방지하기 위해 명시된 헤더 가드를 포함시키도록 한다.
블록 단위 구조에 {} 씌우기
- 코드상에서 발생할 수 있는 구문 에러 방지하기 위해.
한 라인 당 글자수는 적당하기 유지하기
- 몇몇 빌드 시스템에서는 이러한 스타일을 컴파일 시간에 자동으로 체크해주기도 한다.
가능한 경우 앞서 선언하기
이것 대신 :
이런식으로 쓰도록 하자 :
컴파일러 매크로 사용 자제하기
- 컴파일러 정의와 매크로는 컴파일러가 실행되기 전에 전처리과정에서 대체된다. 이는 디버거가 소스의 출처를 알지 못하기 때문에 디버깅이 매우 어려워질 수 있다.
• Part 2: Performance and Safety
코딩 스타일이 프로그램 성능이나 보안에 크게 영향을 미치기도 한다. 주로 컴파일러 최적화나 메모리 관련 보안 이슈들이다.
변수의 스코프 제한
- 변수는 최대한 늦게 선언해야하며 이상적으로는 객체를 초기화 할 수 있어야한다. 변수 범위를 줄이면 메모리 사용량이 줄어들고 더 효율적인 코드가 되어 컴파일러가 코드를 더 최적화하는 데 도움이 된다.
에러 나타낼 때 반환 값 대신 Exception 사용하기
- boost :: optional을 사용하는 것과 같은 반환 값은 무시할 수 있으며 검사하지 않으면 메모리 에러가 발생할 수 있다. 반면에 예외는 포착되어 처리 될 수 있다. 에러 표현시 반환 값 대신 예외를 선언하여 명시적으로 처리하도록 하자.
Raw Memory 접근의 방지
- Raw Memory 접근, 할당 및 반환은 C++에서 올바른 오류를 발생시키지 않고 예상하지 못한 메모리 에러 및 누출을 발생시킬 수 있다.
전역 데이터 사용 피하기
- 여기에는 싱글톤 객체가 포함한다. 전역 데이터는 함수간에 의도하지 않은 부작용을 일으키고 코드를 병렬화하기 어렵거나 불가능하게 만들 수 있습니다. 코드가 당장 병렬화를 목적으로하지 않더라도 미래에는 불가능하게 하도록 코드를 짤 이유가 없다.
Post-increment 대신 Pre-increment 사용하기
- Semantically Correct할 때, Pre-increment는 오브젝트의 사본을 만들 필요가 없기 때문에 Post-increment보다 빠르다.
최대한 Const 키워드 사용하기
- Const는 변수나 함수가 변경 불가능하다는 것을 컴파일러에 알린다. 이는 컴파일러가 코드를 최적화하고 개발자가 함수의 부작용 여부를 알 수 있도록 도와준다. 또한 Const를 사용하면 컴파일러가 불필요하게 데이터를 복사하는 것을 방지한다.
힙 연산보다 스택 연산 선호하기
- 힙 작업은 대부분의 플랫폼에서 다중 스레드 환경에서 성능 저하를 초래하며 신중하게 사용하지 않으면 메모리 오류가 발생할 수 있다. Modern C++11은 사본을 줄이거나 없애서 스택 기반 데이터의 성능을 향상 시키도록 설계된 특별한 이동 작업을 가지고있어 힙 기반 작업과 동등한 단일 스레드 케이스도 가져올 수 있다.
본 포스팅은 기존 작성 글을 바탕으로 해석/편집 한 것입니다.