Naming
명명(naming) 및 주석(comment)을 포함한 모든 코드에서 포괄적인 언어를 사용하고 다른 프로그래머가 무례하거나 불쾌하다고 생각할 수 있는 용어는 사용하지 않는다.
- such as "master" and "slave", "blacklist" and "whitelist", or "redline”
마찬가지로, 특정 사람을 언급하지 않는 한 중립적인 언어를 사용한다.
- such as "they"/"they"/"their", "it"/"its"
General Naming Rules
가독성을 최우선으로, 이름은 명확해야하고 줄임말(프로젝트 외부에서 알기 어려운 약어)은 피한다.
- 단어 내부에서 글자를 삭제하여 축약하는 방식은 사용하지 않음 (cstmr_id ❌ , customer_id ✅)
- 해당 약어가 위키피디아에 있다면 사용해도 괜찮음
짧은 코드 범위에서는 n, i 같은 이름이 괜찮지만, 클래스 범위에서는 더 구체적인 이름을 사용해야 한다.
- 짧은 코드 = 5줄 함수
- kMaxAllowedConnections ✅, kNum ❌
대문자 약어는 하나의 단어처럼 사용
- StartRpc() ✅, StartRPC() ❌
File Names
모두 소문자여야 하며 밑줄(_) 또는 대시(-)를 포함할 수 있다.
- 프로젝트에서 사용하는 규칙이 우선이며, 규칙이 없다면 밑줄을 선호한다.
my_useful_class.cc
my-useful-class.cc
myusefulclass.cc
myusefulclass_test.cc // _unittest and _regtest are deprecated.
파일 확장자 규칙을 따른다.
파일 유형 | 확장자 | 설명 |
소스 파일 | .cc | C++ 소스 코드 파일 |
헤더 파일 | .h | C++ 헤더 파일 |
포함 전용 파일 | .inc | 특정 위치에서 포함되는 파일 |
고유하면서 구체적인 파일명을 사용하고 시스템 헤더 파일과 이름 충돌을 피한다. (db.h, string.h)
- 너무 일반적이지 않고 구체적인 의미를 담아야한다.
- 좋은 예시 vs 나쁜 예시
logs.h ❌ (너무 일반적)
http_server_logs.h ✅ (더 구체적인 의미 전달)
foo_bar.h ✅ (FooBar 클래스를 정의하는 파일)
foo_bar.cc ✅ (FooBar 클래스의 구현 파일)
Type Names
항상 대문자로 시작하고, 단어 사이에 _ (언더스코어)를 사용하지 않는다.
새로운 단어의 시작은 대문자로 구분한다(PascalCase)
모든 타입(Class, Struct, Type Alias, Enum, Template parameters)에 동일한 규칙을 적용한다.
// classes and structs
class UrlTable { ...
class UrlTableTester { ...
struct UrlTableProperties { ...
// typedefs
typedef hash_map<UrlTableProperties *, std::string> PropertiesMap;
// using aliases
using PropertiesMap = hash_map<UrlTableProperties *, std::string>;
// enums
enum class UrlTableError { ...
Variable Names
변수 및 함수 매개변수는 snake_case (소문자 + 언더스코어) 형식을 사용한다.
std::string table_name; // ✅ 올바른 변수명
int max_value; // ✅ 올바른 변수명
void process_data(int input_value) { ... } // ✅ 함수 매개변수도 snake_case 사용
std::string tableName; // ❌ camelCase 사용 금지
std::string TableName; // ❌ PascalCase 사용 금지
void ProcessData(int InputValue) { ... } // ❌ 변수명에 대문자 사용 금지
Class의 데이터 멤버는 snake_case_ (언더스코어로 끝나도록) 형식을 사용한다.
class TableInfo {
private:
std::string table_name_; // ✅ 클래스 데이터 멤버는 _로 끝남
int record_count_; // ✅ 클래스 내부 변수는 _로 끝남
static Pool<TableInfo>* pool_; // ✅ 정적 변수도 동일한 규칙 적용
};
class TableInfo {
private:
std::string tableName; // ❌ camelCase 사용 금지
int recordCount; // ❌ camelCase 사용 금지
static Pool<TableInfo>* Pool; // ❌ PascalCase 사용 금지
};
Struct 의 데이터 멤버는 일반 변수처럼 snake_case를 사용한다.
struct UrlTableProperties {
std::string name; // ✅ 일반 변수처럼 snake_case 사용
int num_entries; // ✅ 정수형 변수도 snake_case 사용
static Pool<UrlTableProperties>* pool; // ✅ 정적 변수도 동일한 규칙 적용
};
struct UrlTableProperties {
std::string name_; // ❌ 구조체에서는 `_`를 붙이지 않음
int numEntries; // ❌ camelCase 사용 금지
static Pool<UrlTableProperties>* Pool_; // ❌ PascalCase 및 `_` 사용 금지
};
Constant Names
constexpr 또는 const 변수는 k로 시작해야하며, 다음 단어부터는 CamelCase를 적용한다. (kCamelCase)
단어 구분이 어려운 경우에만 _(언더스코어)를 사용한다.
const int kDaysInAWeek = 7; // ✅ 'k'로 시작, CamelCase 사용
constexpr double kPi = 3.14159; // ✅ 'k' 사용, 프로그램 실행 중 변하지 않음
const int kAndroid8_0_0 = 24; // ✅ 언더스코어 사용 (숫자 구분이 어려운 경우)
template <typename T>
constexpr int kMaxBufferSize = 1024; // ✅ 템플릿 변수지만, 모든 인스턴스에서 상수로 유지됨
지역 변수의 경우에는 적용할 필요가 없다.
void ComputeFoo(absl::string_view suffix) {
const absl::string_view kPrefix = "prefix"; // ✅ 사용 가능 (지역 변수지만, 프로그램 실행 중 변하지 않음)
const absl::string_view prefix = "prefix"; // ✅ 일반적인 네이밍도 허용됨
}
void ComputeFoo(absl::string_view suffix) {
const std::string kCombined = absl::StrCat(kPrefix, suffix); // ❌ 잘못된 예제
Function Names
일반적인 함수는 PascalCase 를 사용해야 한다.
void AddTableEntry(); // ✅ 올바른 예시
void DeleteUrl(); // ✅ 올바른 예시
void OpenFileOrDie(); // ✅ 올바른 예시
void add_table_entry(); // ❌ 함수는 PascalCase를 사용해야 함
void delete_url(); // ❌ 함수 이름을 소문자로 작성하면 안 됨
단, getter와 setter의 경우에는 변수처럼 snake_case 를 사용한다.
class Counter {
public:
int count() const { return count_; } // ✅ 변수처럼 `snake_case` 스타일 사용 가능
void set_count(int count) { count_ = count; } // ✅ setter도 변수 스타일 허용
private:
int count_;
};
Namespace Names
소문자로 작성하며, 단어 사이에는 _(언더스코어)를 사용한다.
최상위 네임스페이스는 프로젝트 또는 팀 이름을 반영해야한다.
namespace websearch { // ✅ 프로젝트 이름을 최상위 네임스페이스로 사용
namespace index_util { // ✅ 단어 구분 시 언더스코어 사용
void BuildIndex();
} // namespace index_util
} // namespace websearch
namespace WebSearch { // ❌ 대문자로 시작하면 안 됨
namespace IndexUtil { // ❌ CamelCase 사용 금지
void BuildIndex();
} // namespace IndexUtil
} // namespace WebSearch
잘 알려진 최상위 네임스페이스(std, boost 등)와 충돌하지 않도록 해야한다.
네임스페이스 이름을 축약하면 안된다.
namespace websearch { // ✅ 최상위 네임스페이스 = 프로젝트 이름
namespace index { // ✅ 서브 네임스페이스 (구체적인 역할을 반영)
void BuildIndex();
} // namespace index
} // namespace websearch
namespace util { // ❌ "util"은 너무 일반적이며 충돌 가능성이 높음
namespace index {
void BuildIndex();
} // namespace index
} // namespace util
Enumerator Names
모든 열거형(enum) 값은 kCamelCase 스타일을 사용해야 한다.
enum class UrlTableError {
kOk = 0, // ✅ 올바른 네이밍
kOutOfMemory, // ✅ CamelCase + k 접두사
kMalformedInput, // ✅ CamelCase + k 접두사
};
enum class AlternateUrlTableError {
OK = 0, // ❌ 매크로처럼 작성하면 안 됨
OUT_OF_MEMORY = 1,
MALFORMED_INPUT = 2,
};
Macro Names
매크로는 가급적 사용하지 않는다. 꼭 필요한 경우 SCREAMING_SNAKE_CASE(대문자+ _ )를 사용한다.
매크로 이름에는 프로젝트 접두사(prefix)를 포함한다.
#define MYPROJECT_ROUND(x) ((x) + 0.5) // ✅ 프로젝트 접두사 포함
#define MYPROJECT_MAX_BUFFER_SIZE 1024 // ✅ 프로젝트 접두사 포함
#define DEBUG_MODE 1 // ✅ 글로벌 매크로는 대문자로 작성
#define MyProjectRound(x) ((x) + 0.5) // ❌ PascalCase 사용 금지
#define my_project_max_buffer_size 1024 // ❌ 소문자 사용 금지
#define DebugMode 1 // ❌ CamelCase 사용 금지
일반적인 코드에서는 constexpr, inline, const 등을 대신 사용할 것을 권장한다.
- 예시 1. 매크로 사용의 좋지 않은 방법과 그 대안
#define SQUARE(x) ((x) * (x)) // ❌ 위험: x가 식일 경우 예상치 못한 동작 가능
int result = SQUARE(3 + 1); // 예상: (3+1) * (3+1) = 16
// 실제 동작: (3 + 1 * 3 + 1) = 7 (잘못된 결과)
// constexpr을 사용하는 방법
constexpr int Square(int x) {
return x * x;
}
Exceptions to Naming Rules
C 표준 라이브러리와 유사한 함수는 기존 스타일을 유지한다.
int bigopen(const char* filename, int flags); // ✅ 기존 open() 함수 스타일 유지
int BigOpen(const char* filename, int flags); // ❌ C 스타일 함수는 PascalCase 사용하지 않음
C 스타일 타입 정의 (typedef or using)은 기존 스타일을 유지한다.
typedef unsigned int uint; // ✅ 기존 C 스타일 유지
using uint = unsigned int; // ✅ C++ 스타일 유지
typedef unsigned int UnsignedInt; // ❌ `typedef`는 일반적으로 소문자 사용
STL 스타일을 따르는 경우, 기존 스타일을 유지한다.
template <typename Key, typename Value>
class sparse_hash_map {
// ✅ STL 스타일 유지
};
template <typename Key, typename Value>
class SparseHashMap { // ❌ STL 스타일을 따르지 않음
};
상수(constexpr 또는 #define)는 기존 C 스타일(SCREAMING_SNAKE_CASE)을 유지해야 한다.
#define LONGLONG_MAX 9223372036854775807LL // ✅ 기존 INT_MAX 스타일 유지
constexpr long long LONGLONG_MAX = 9223372036854775807LL; // ✅ 같은 스타일 유지
constexpr long long LongLongMax = 9223372036854775807LL; // ❌ 기존 C 스타일과 다름
'CSE > 알쓸모' 카테고리의 다른 글
Google C++ Style Guide 정리하기 - Formatting (0) | 2025.03.05 |
---|---|
Google C++ Style Guide 정리하기 - Comments (0) | 2025.03.04 |
Google C++ Style Guide 정리하기 - Functions (0) | 2025.03.02 |
Google C++ Style Guide 정리하기 - Classes (2) | 2025.03.01 |
어도비(adobe) 조기 취소 수수료 안내고 싶은데. (0) | 2025.02.28 |