라인 길이
코드의 각 줄은 최대 80자 이하로. 일관성과 가독성이 중요
비 ASCII 문자
비 ASCII문자는 UTF-8 형식을 사용해야함.
공백 vs 탭
공백만 사용하고 한번에 2칸정도 들여쓰기. 탭을 사용하지말것.
사용한다면 탭시 공백이 나오도록 에디터를 설정
함수 선언 및 정의
한줄에 들어가지 않는 매개변수는 줄바꿈
ReturnType LongClassName::ReallyReallyReallyLongFunctionName( Type par_name1, // 4 space indent Type par_name2, Type par_name3) { DoSomething(); // 2 space indent ... }
명백하게 사용하지 않는 매개변수는 변수 이름을 주석처리
class Shape { public: virtual void Rotate(double radians) = 0; }; class Circle : public Shape { public: void Rotate(double radians) override; }; void Circle::Rotate(double /*radians*/) {}
람다식
다른 모든 함수와 마찬가지로 형식화, 쉼표로 구분
int x = 0; auto x_plus_n = [&x](int n) -> int { return x + n; }
함수 호출
인수가 모두 한 행에 들어가지않는 경우 첫번째 인수와 정렬
bool result = DoSomething(averyveryveryverylongargument1, argument2, argument3);
인수는 선택적으로 4개의 들여쓰기 후 후속행에만 배치할 수도 있음
if (...) { ... ... if (...) { bool result = DoSomething( argument1, argument2, // 4 space indent argument3, argument4); ... }
한 줄에 여러개의 인수가 있는 경우 구성하는 식이 복잡하거나 가독성이 떨어지면
해당인수를 설명하는 변수를 만들어 쓸것
int my_heuristic = scores[x] * y + bases[x]; bool result = DoSomething(my_heuristic, x, y, z);
또는 혼란스러운 내용을 설명하는 주석을 같은 줄에 넣을 것
bool result = DoSomething(scores[x] * y + bases[x], // Score heuristic. x, y, z);
가독성을 위해 때로는 형식화함.
// Transform the widget by a 3x3 matrix. my_widget.Transform(x1, x2, x3, y1, y2, y3, z1, z2, z3);
중괄호가 들어가는 초기화 목록
중괄호를 아래와 같이 형식을 지정함
// Examples of braced init list on a single line. return {foo, bar}; functioncall({foo, bar}); std::pair<int, int> p{foo, bar}; // When you have to wrap. SomeFunction( {"assume a zero-length name before {"}, some_other_function_parameter); SomeType variable{ some, other, values, {"assume a zero-length name before {"}, SomeOtherType{ "Very long string requiring the surrounding breaks.", some, other values}, SomeOtherType{"Slightly shorter string", some, other, values}}; SomeType variable{ "This is too long to fit all in one line"}; MyType m = { // Here, you could also break before {. superlongvariablename1, superlongvariablename2, {short, interior, list}, {interiorwrappinglist, interiorwrappinglist2}};
조건부 (if문)
모든 경우에 if와 여는 괄호 사이에 공백이 있어야 함
if (condition) { // Good - proper space after IF and before {.
가독성을 위해 짧은 조건문 한줄에 써도 되나 else가 없을때만
if (x == kFoo) return new Foo();
단일 행일 경우 중괄호 써도 안써도 허용. 일부에서는 반드시 필요로하기도함.
if (condition) DoSomething(); // 2 space indent. if (condition) { DoSomething(); // 2 space indent. }
else를 사용하면 둘다 중괄호를 사용할 것
if (condition) { foo; } else { bar; }
루프 (for문) 및 스위치문
case 안에는 중괄호를 써도되고 안써도되고.
기본 케이스를 절대로 실행해서는 안되는 경우 에러로 처리
switch (var) { case 0: { // 2 space indent ... // 4 space indent break; } case 1: { ... break; } default: { assert(false); } }
단일 명령문의 경우 중괄호는 선택적
for (int i = 0; i < kSomeNumber; ++i) printf("I love you\n"); for (int i = 0; i < kSomeNumber; ++i) { printf("I take it back\n"); }
빈 루프는 중괄호 없는 continue를 제외하면 항상 중괄호를 사용. 중괄호 없이 세미콜론 하나만 찍지말것.
while (condition) { // Repeat test until it returns false. } for (int i = 0; i < kSomeNumber; ++i) {} // Good - one newline is also OK. while (condition) continue; // Good - continue indicates no logic.
포인터 및 참조식
마침표 및 화살표 주변에 공백이 없어야함.
x = *p; p = &x; x = r.y; x = r->y;
포인터 변수 및 인수 선언시에 별표를 변수 이름에 인접하는 것은 허용
// These are fine, space preceding. char *c; const string &str; // These are fine, space following. char* c; const string& str;
동일한 선언에서 포인터 및 참조가 있는 변수는 허용하지 않음.
int x, *y; // Disallowed - no & or * in multiple declaration char * c; // Bad - spaces on both sides of * const string & str; // Bad - spaces on both sides of &
부울 표현식
표준 행 길이보다 긴 부울식을 사용할 때는 분리 방법을 일관되게 유지. 마지막에 붙이던가 시작부분에 붙이던가
if (this_one_thing > this_other_thing && a_third_thing == a_fourth_thing && yet_another && last_one) { ... }
반환 값
리턴값을 괄호로 묶지 말 것. 복잡한 식일 경우에만 허용
return result; // No parentheses in the simple case. // Parentheses OK to make a complex expression more readable. return (some_long_condition && another_condition);
변수 및 배열 초기화
=, (), {} 사이에서만 선택할 것
int x = 3; int x(3); int x{3}; string name = "Some Name"; string name("Some Name"); string name{"Some Name"};
전처리기 지시문
전처리기 지시문은 항상 줄의 시작에 있어야함. 들여쓰기를 하지 말것.
// Good - directives at beginning of line if (lopsided_score) { #if DISASTER_PENDING // Correct -- Starts at beginning of line DropEverything(); # if NOTIFY // OK but not required -- Spaces after # NotifyClient(); # endif #endif BackToNormal(); }
클래스 형식
public:, protected;, private: 키워드는 한칸 들여쓰기.
맨 첫줄을 제외하고는 이런 키워드 앞에는 빈 줄이 와야함. 키워드 뒤에는 빈줄을 만들지 말것.
public, protected, private 순서대로 선언할것.
class MyClass : public OtherClass { public: // Note the 1 space indent! MyClass(); // Regular 2 space indent. explicit MyClass(int var); ~MyClass() {} void SomeFunction(); void SomeFunctionThatDoesNothing() { } void set_some_var(int var) { some_var_ = var; } int some_var() const { return some_var_; } private: bool SomeInternalFunction(); int some_var_; int some_other_var_; };
생성자 이니셜라이저 목록
모두 한 행에 있거나 스페이스 4칸 들여쓰기 된 후속행에 서술
// When everything fits on one line: MyClass::MyClass(int var) : some_var_(var) { DoSomething(); } // If the signature and initializer list are not all on one line, // you must wrap before the colon and indent 4 spaces: MyClass::MyClass(int var) : some_var_(var), some_other_var_(var + 1) { DoSomething(); } // When the list spans multiple lines, put each member on its own line // and align them: MyClass::MyClass(int var) : some_var_(var), // 4 space indent some_other_var_(var + 1) { // lined up DoSomething(); } // As with any other code block, the close curly can be on the same // line as the open curly, if it fits. MyClass::MyClass(int var) : some_var_(var) {}
네임스페이스 서식
네임스페이스의 내용은 들여쓰기하지 않음
namespace { void foo() { // Correct. No extra indentation within namespace. ... } } // namespace
가로 공백
위치따라 다름. 줄 끝에 공백을 두지말 것.
- 일반
열려있는 중괄호 앞에는 항상 공백
세미콜론에는 공백이 없음.
중괄호 안의 공백은 선택사항
상속 및 초기화에서 콜론 주위에 공백
빈 괄호 안에는 공백이 없어야함
void f(bool b) { // Open braces should always have a space before them. ... int i = 0; // Semicolons usually have no space before them. // Spaces inside braces for braced-init-list are optional. If you use them, // put them on both sides! int x[] = { 0 }; int x[] = {0}; // Spaces around the colon in inheritance and initializer lists. class Foo : public Bar { public: // For inline function implementations, put spaces between the braces // and the implementation itself. Foo(int b) : Bar(), baz_(b) {} // No spaces inside empty braces. void Reset() { baz_ = 0; } // Spaces separating braces from implementation. ...
- 루프 및 조건부
조건 및 루프에서 키워드 뒤에 공백, else 주위 공백
일반적으로 중괄호 안은 공백이 없음
for루프는 세미콜론 다음 공백
case 콜론 앞에 공백이 없음
if (b) { // Space after the keyword in conditions and loops. } else { // Spaces around else. } while (test) {} // There is usually no space inside parentheses. switch (i) { for (int i = 0; i < 5; ++i) { // Loops and conditions may have spaces inside parentheses, but this // is rare. Be consistent. switch ( i ) { if ( test ) { for ( int i = 0; i < 5; ++i ) { // For loops always have a space after the semicolon. They may have a space // before the semicolon, but this is rare. for ( ; i < 5 ; ++i) { ... // Range-based for loops always have a space before and after the colon. for (auto x : counts) { ... } switch (i) { case 1: // No space before colon in a switch case. ... case 2: break; // Use a space after a colon if there's code after it.
- 연산자
할당 연산자는 주위에 공백이 있음.
이진 연산자는 대체로 공백이 있지만 제거하는것은 괜찮음.
단항 연산자는 인수를 구분하는 공백이 없어야함
// Assignment operators always have spaces around them. x = 0; // Other binary operators usually have spaces around them, but it's // OK to remove spaces around factors. Parentheses should have no // internal padding. v = w * x + y / z; v = w*x + y/z; v = w * (x + z); // No spaces separating unary operators and their arguments. x = -5; ++x; if (x && !y)
- 템플릿 및 캐스트
<> 사이에 공백 없어야함, 다만 포인터는 예외
// No spaces inside the angle brackets (< and >), before // <, or between >( in a cast std::vector<string> x; y = static_cast<char*>(x); // Spaces between type and pointer are OK, but be consistent. std::vector<char *> x;
세로 공백
웬만하면 사용을 최소화하자. 할 필요가 없을 때 빈 줄을 만들지 말자.
'프로그래밍 공부 > Coding convention' 카테고리의 다른 글
스타일 / 네이밍 / 주석 (0) | 2019.02.21 |
---|---|
Google C++ Style Guide - 이름 짓기 (Naming) (0) | 2018.11.30 |