주석이 매우 중요하지만, 최고의 코드는 자체 문서화이다.
변수에 합리적인 이름을 부여하는 것이 주석을 통해 설명해야 하는 모호한 이름을 사용하는 것보다 훨씬 낫다.
다음 규칙들은 무엇을 어디에 댓글을 달아야 하는지를 설명한다.
Comment Style
// 또는 /* */ 구문을 일관성있게 사용한다.
- // 가 훨씬 더 일반적
- 어떤 스타일을 어디에 사용하는지 일관성을 유지
File Comments
모든 파일의 맨 위에 라이선스 주석(license boilerplate)을 작성한다.
- 프로젝트에 따라 Apache, BSD, MIT, GPL 등 적절한 라이선스를 선택
헤더 파일에 여러 개의 관련 클래스를 포함하는 경우, 해당 파일이 어떤 개념을 다루는지 설명해야 한다.
- 파일의 역할을 한 문단으로 설명
- “이 파일이 무엇을 포함하는지” 명확히 서술
- 파일에 추가할 내용과 추가하면 안될 내용을 정리하면 나중에 관리하기 용이해짐
// frobber.h - Defines the Frobber class and related utilities.
//
// This file provides an abstraction for frobbing data structures
// in an efficient manner. It includes:
// - `Frobber`: A base class for handling frobbing operations
// - `FrobberFactory`: A factory class for creating `Frobber` instances
//
// If you need additional frobbing utilities, consider adding them here.
#ifndef FROBBER_H_
#define FROBBER_H_
class Frobber { ... };
class FrobberFactory { ... };
#endif // FROBBER_H_
일반적으로 .cc 파일은 헤더 파일의 구현체이므로, 주석이 필요하지 않다.
- 그러나 헤더 파일이 없는 .cc 파일이라면, 개념을 설명하는 주석을 추가해야함
파일 상단에 author 라인을 포함하지 않는다.
- 팀 프로젝트에서는 여러 사람이 코드를 수정하므로 author 라인이 불필요함
- Git 과 같은 버전 관리 시스템이 변경 기록을 추적하므로, 따로 작성할 필요가 없음
- 예시 1. 잘못된 주석 (author 라인 포함)
// Copyright 2024 MyProject Developers
// Author: John Doe
//
// Licensed under the Apache License, Version 2.0 (the "License")...
Struct and Class Comments
무엇을 위한 것인지, 어떻게 사용해야 하는지를 설명하는 주석이 첨부되어야 한다.
- 예시 1.
// Iterates over the contents of a GargantuanTable.
// Example:
// std::unique_ptr<GargantuanTableIterator> iter = table->NewIterator();
// for (iter->Seek("foo"); !iter->done(); iter->Next()) {
// process(iter->key(), iter->value());
// }
class GargantuanTableIterator {
...
};
- 예시 2.
// Stores configuration settings for the application.
struct Config {
int timeout; // Request timeout in milliseconds.
bool enable_feature; // Whether to enable the experimental feature.
};
Function Comments
함수 선언부(헤더 파일 .h)와 정의부(구현 파일 .cc)의 주석은 각각 다른 목적을 가진다.
- 선언부 주석 : 함수의 사용법(입출력, 제약 조건, 예제 등)을 설명
- 정의부 주석 : 함수의 내부 동작 방식과 구현상의 중요한 고려사항을 설명
단순한 Getter/Setter 함수는 주석을 생략한다.
함수가 포인터를 받으면 nullptr 허용 여부를 명확하게 설명한다.
생성자와 소멸자는 특별한 동작이 없다면 주석을 생략한다.
Variable Comments
변수 이름은 그 목적을 설명할 수 있도록 직관적으로 작성해야 한다.
클래스 멤버 변수는 이름만으로 충분한 의미를 전달할 수 있으면 주석을 생략할 수 있다.
nullptr, -1 등의 센티널 값(Sentinel Values) 을 사용할 경우, 반드시 의미를 설명해야 한다.
전역 변수(Global Variables)는 반드시 주석을 포함해야 하며, “왜 전역 변수로 선언했는지” 명확히 설명해야 한다.
Implementation Comments
어렵거나 복잡하거나 중요한 부분에는 반드시 코드 앞에 주석을 추가해야 한다.
// Uses a binary search to find the insertion point for the new element.
// This ensures O(log N) insertion time in a sorted list.
auto it = std::lower_bound(sorted_list.begin(), sorted_list.end(), new_element);
sorted_list.insert(it, new_element);
함수 인자의 의미가 명확하지 않으면 개선 방법을 고려해야 한다.
- 예시 1. literal constant 제거, 명명된 상수 사용
// const DecimalNumber product = CalculateProduct(values, 7, false, nullptr);
constexpr int kDefaultPrecision = 7;
constexpr bool kDisableCache = false;
const DecimalNumber product = CalculateProduct(values, kDefaultPrecision, kDisableCache, nullptr);
코드가 자체적으로 의미를 전달 할 수 있도록 노력하고, 불필요한 주석은 피해야 한다.
- 예시 1. std::find() 는 원래 특정 요소를 찾는 함수이므로 주석이 불필요
// Find the element in the vector.
if (std::find(v.begin(), v.end(), element) != v.end()) {
Process(element);
}
- 예시 2. 주석으로 코드의 의도를 설명(”이전에 처리된 요소는 다시 처리하지 않는다”
// Process "element" unless it was already processed.
if (std::find(v.begin(), v.end(), element) != v.end()) {
Process(element);
}
Self-Describing Code 활용 (코드가 스스로 의미를 전달할 수 있도록)
if (!IsAlreadyProcessed(element)) {
Process(element);
}
Punctuation, Spelling, and Grammar
구두점, 철자, 문법을 올바르게 사용해서 가독성이 좋아야 한다.
int count = 0; // Counts the number of processed elements.
코드 리뷰에서 주석을 지적 받는 것이 불편하더라도 최종적으로는 코드의 가독성에 도움이 된다.
// Intializes the buffer and sets its size. // ❌ 'Intializes' → 'Initializes'
buffer.Init(size);
TODO Comments
TODO 주석은 임시 코드, 단기 해결책, 또는 완벽하지 않은 코드에서 사용해야 한다.
TODO 는 항상 대문자로 작성하며, 이후에 관련 정보를 포함해야 한다.
TODO에 버그 ID, 담당자 이름, 이메일, 또는 관련 문서를 포함해야 한다.
// TODO: bug 12345678 - Remove this after the 2047q4 compatibility window expires.
// TODO: example.com/my-design-doc - Manually fix up this code the next time it's touched.
// TODO(bug 12345678): Update this list after the Foo service is turned down.
// TODO(John): Use a "\*" here for concatenation operator.
단순한 문구보다는 언제 해결해야 하는지 명확한 조건(날짜 또는 특정 이벤트)을 포함해야 한다.
- Fix by November 2005 , Remove this code when all clients can handle XML responses.
'CSE > 알쓸모' 카테고리의 다른 글
Google C++ Style Guide 정리하기 - Formatting (0) | 2025.03.05 |
---|---|
Google C++ Style Guide 정리하기 - Naming (0) | 2025.03.03 |
Google C++ Style Guide 정리하기 - Functions (0) | 2025.03.02 |
Google C++ Style Guide 정리하기 - Classes (2) | 2025.03.01 |
어도비(adobe) 조기 취소 수수료 안내고 싶은데. (0) | 2025.02.28 |