본문 바로가기
C&C++/Google Style Guide

Naming

by Ken out of ken 2024. 7. 17.

Background

C++는 구글의 많은 오픈 소스 프로젝트에서 사용되는 주요 개발 언어 중 하나입니다

모든 C++프로그래머가 알다시피, C++은 강력한 기능을 제공하지만, 이러한 강력함은 복잡성을 동반하며, 이로 인해 코드가 버그가 발생하기 쉽고, 읽기 및 유지 관리가 어려워질 수 있습니다

 

이 가이드의 목표는 C++ 언어 기능을 생산적으로 사용할 수 있도록 하면서도 코드의 복잡성을 관리하는 데 있습니다

이 규칙들은 코드 베이스를 관리 간으하게 유지하는 동시에 개발자들이 C++ 언어 기능을 효과적으로 사용할 수 있도록 돕는 것을 목표로 합니다

 

스타일, 또는 가독성이라고 불리우는 것은 우리의 C++ 코드에 적용되는 관습을 의미합니다

스타일이라는 용어는 다소 잘못된 명칭일 수 있는데, 이 규칙들은 단순히 소스 파일 형식만 다루는 것이 아니라 그 이상을 포괄하기 때문입니다

 

구글이 개발하는 대부분의 오픈 소스 프로젝트는 이 가이드의 요구 사항을 따릅니다

 

이 가이드는 C++ 튜토리얼이 아닙니다! 

우리는 독자가 C++ 언어에 익숙하다는 가정하에 작성되었습니다

Goals of the Style Guide

이 문서를 작성한 이유가 뭘까요?

 

우리가 이 가이드에 충족해야 한다고 믿는 몇 가지 핵심 목표가 있습니다

이러한 목표들은 각각의 개별 규칙을 뒷받침하는 근본적인 이유입니다

이 개념을 강조함으로써 규칙이 존재하는 이유와 특정 결정이 내려진 이유를 명확하게 이해할 수 있도록 돕고자 합니다

각 규칙이 어떤 목표를 달성하기 위한 것인지르 ㄹ이해하면, 규칙을 언제 예외적으로 적용할 수 있는지(일부는 가능) 명확해지며, 규칙을 변

경하려면 어떤 대안이나 논의가 필요한지도 알 수 있을 것입니다

 

목표는 다음과 같습니다

 

  • 스타일 규칙은 그 가치가 충분해야 합니다
스타일 규칙의 이점은 모든 엔지니어가 기억할 가치가 있을 만큼 충분히 커야 합니다
  • 작성자보다는 독자를 최적화하세요
우리의 코드베이스(및 제출된 대부분의 구성요소)는 오랜 기간 유지될 것으로 예상되죠
그 결과, 대부분의 코드에서는 작성보다 읽는 데 더 많은 시간이 소요됩니다
우리는 코드 작성의 용이성보다는 평균적인 소프트웨어 엔지니어가 코드를 읽고 유지 관리하며 디버깅하는 경험을 최적화하기로 선택했습니다
"독자를 위해 흔적을 남겨라" 는 이 원칙은 중요한 세부 사항 중 하나입니다
코드 조각에서 예상치 못한 일(e.g.: 포인터 소유권 이전)이 발생할 때, 사용 지점에서 독자에게 텍스트 힌트를 남기는 것이 유용합니다
예를 들어 std::unique_ptr는 호출지점에서 소유권 이전을 명확하게 나타냅니다
  • 기존 코드와 일관성을 유지하세요
우리의 코드베이스를 통해 하나의 스타일을 일관성 있게 사용한다면 다른 (더 중요한) 문제들에 집중할 수 있죠
일관성은 자동화가 가능합니다: 코드 형식을 수정해 주거나 #include 파일을 조정하는 도구는 코드가 도구의 기대와 일관성이 맞을 때에 사용됩니다
많은 경우 "일관성 있게 하라"라는 귀속된 규칙은 그냥 "그냥 하나로 통일하고 더 이상 신경 쓰지 마라"는 의미입니다
이러한 점에 대해 유연성을 허용할 수 있는 잠재적인 가치로는 사람들이 이에 대해 논쟁하는데 드는 비용을 상쇄하지 못합니다
쨋거나, 일관성에는 한계가 존재합니다
명확한 기술적 논쟁이 없거나 장기적인 방향이 없을 때는 좋은 타협점이 될 수 있죠
그러나 일관성은 새로운 것에 대한 이익을 고려하지 않고 오래된 스타일을 고수하는 것을 정당화하는데에 사용되어서는 안 되며, 코드베이스가 새로운 스타일로 나아가는 성향을 고려해야 합니다
  • 적절한 경우 더 넓은 C++ 커뮤니티와 일관성을 유지하세요
다른 조직 내에서의 C++ 사용 방식과 일관성은 우리 코드베이스 내에서의 일관성과 마찬가지로 가치가 있습니다
C++ 표준에서 어떤 기능이 문제를 해결하거나 어떤 관용구가 널리 알려져 있고 받아들여진다면, 그것으 사용하는 편이 좋습니다
그러나 표준 기능과 관용구가 결함이 있거나 우리의 코드베이스의 요구를 염두에 두고 설계되지 않알을 경우에는 이를 제한하거나 금지하는 것이 적절합니다
일부 경우에는 표준 라이브러리 대신 우리가 직접 만든 라이브러리나 타사 라이브러리를 선호하기도 하죠
이는 그 라이브러리가 더 우수하다고 판단되거나 표준 인터페이스로 코드베이스를 전환할 가치가 없기 때문입니다
  • 놀랍거나 위험한 구조를 피하세요
C++은 얼핏 보기에는 놀랍거나 위험할 수 있는 기능들을 가지고 있습니다
스타일 가이드의 몇 가지 제한 사항은 이러한 함정에 빠지지 않도록 하기 위해 존재합니다
이러한 제한 사항에 대한 예외 허용 기준은 매우 높습니다
이러한 규칙을 무시하는 것은 종종 프로그램의 정확성을 위험에 빠뜨릴 수 있기 때문입니다
  • 일반적인 C++ 프로그래머가 찾기 힘들거나 유지하기 힘든 구조는 피하세요
C++은 코드의 복잡성을 증가시킬 수 있는 기능들이 있는데, 이는 일반적으로 적합하지 않을 수 있습니다
널리 사용되는 코드에서는 복잡한 구현의 이점이 널리 퍼져서 더 수용 가능할 수 있으며, 이러한 복잡성을 이해하는 데 드는 비용은 ㄴ새로운 코드 부분을 작업할 때마다 반복해서 지불할 필요는 없습니다
의심스러울 경우, 이러한 유형의 규칙에 대한 예외는 프로젝트 리더에게 문의하여 얻을 수 있습니다
이는 특히 코드 소유권과 팀 구성원이 시간이 지남에 따라 변경될 수 있기 때문에 중요합니다
현재 해당 코드의 모드 작업자가 이를 이해하더라도, 몇 년 후에 그 이해가 계속 유지된다는 보장은 없습니다
  • 규모에 유의하세요
수억 줄의 코드베이스와 수천 명의 엔지니어가 있는 상황에서, 한 엔지니어의 실수나 단순화가 많은 사람들에게 비용을 초래할 수 있죠
예를 들어 글로벌 네임스페이스를 오염시키는 것은 특히 피해야합니다
수억 줄의 코드베이스에서 네임 충돌이 발생하면 이를 처리하기 어렵고 피하기가 힘듭니다
  • 필요한 경우 최적화는 양보하세요
때로는 성능 최적화가 필요할 수 있으며, 이는 이 문서의 다른 원칙들과 상충될 수 있습니다

 

이 문서의 의도는 합리적인 제약과 함께 최대한의 지침을 제공하는 것입니다

항상 상식과 좋은 취향이 우선돼야 합니다

여기서 말하는 '상식과 좋은 취향'은 개인적 선호나 팀의 선호가 아닌, 구글 C++ 커뮤니티 전체에서 확립된 관습을 의미합니다

교묘하거나 특이한 구조를 사용하는 것에 대해 의심스러워해야 하며, 금지 조항이 없다고 해서 그것을 사용할 수 있다는 의미는 아닙니다

판단을 잘하고, 확신이 서지 않는 경우에는 프로젝트 리더에게 추가적인 의견을 구하세요

 

 

C++ version

현재 코드는 C++20을 목표로 하며, C++23 기능은 사용하지 않아야 합니다

이 가이드에서 목표로 하는 C++ 버전은 시간이 지나면서 점진적으로 발전할 것입니다

 

비표준 확장 사용하지 마세요

 

C++17 C++20의 기능을 사용할 때는 다른 환경으로의 이식성을 고려해야 합니다

 

Header Files

일반적으로, 모든 .cc 파일에는 관련. h 파일이 있어야 합니다

유닛테스트나 main() 함수만 포함된 작은 .cc 파일 등 몇 가지 일반적인 예외가 있습니다

 

헤더파일을 적절하게 사용하면 코드의 가독성, 크기 및 성능에 큰 차이를 만들 수 있습니다

 

다음 규칙들은 헤더 파일 사용 시 발생할 수 있는 여러 가지 함정을 안내합니다

Naming

The most important consistency rules are those that govern naming 

가장 중요한 일관성 규칙으로는 이름 지정이 있습니다

 

The style of a name immediately informs us what sort of thing the named entity is: a type, a variable, a function, a constant, a macro, etc., without requiring us to search for the declaration of that entity.

이름의 형식은 해당 이름이 무엇을 의미하는지를 즉시 알려줍니다: 타입, 변수, 함수, 상수, 매크로 등등... 선언부를 찾아볼 필요 없이 말이죠.

 

The pattern-matching engine in our brains relies a great deal on these naming rules.

우리 두뇌의 패턴 매칭 엔진은 이러한 이름 지정 방식에 크게 의존합니다

 

Naming rules are pretty arbitrary, but we feel that consistency is more important than individual preferences in this area, so regardless of whether you find them sensible or not, the rules are the rules.

이름 지정 규칙은 꽤나 독단적으로 보입니다, 하지만 이러한 일관성이 이 영역에서는 개인의 선호보다 훨씬 중요하며, 당신이 그게 합리적이든 아니든 상관없이 규칙은 규칙입니다

 


General Naming Rules

Optimize for readability using names that would be clear even to people on a different team.

  • 다른 팀의 사람들도 의미를 분명하게 받아들일 수 있도록 이름의 가독성을 유지하세요

 

Use names that describe the purpose or intent of the object.

  • 객체의 의도나 의미를 묘사하는 이름을 사용하세요

 

Do not worry about saving horizontal space as it is far more important to make your code immediately understandable by a new reader.

  • 수평 공간을 아끼는 걱정은 하지 말고 새로운 독자가 바로 이해할 수 있도록 코드를 짜는 것이 더 중요합니다

 

Minimize the use of abbreviations that would likely be unknown to someone outside your project (especially acronyms and initialisms).

  • 프로젝트 외부인이 알지 못하는 약어 사용을 최소화하세요 (특히 줄임말 및 두문자어)

 

Do not abbreviate by deleting letters within a word.

  • 단어 안의 문자를 삭제하여 축약하지 마세요

 

As a rule of thumb, an abbreviation is probably OK if it's listed in Wikipedia.

  • 경험상, Wikipedia에 올라와 있는 약어는 가능할 겁니다

 

Generally speaking, descriptiveness should be proportional to the name's scope of visibility.

  • 일반적으로, 이름의 설명성은 그 이름의 가시성 범위에 비례해야 합니다

 

For example, n may be a fine name within a 5-line function, but within the scope of a class, it's likely too vague.

  • 예를 들어, n은 5줄 정도 되는 함수 내에서는 괜찮을지라도, class 범위 내에는 그 의미가 불분명하죠
class MyClass {
 public:
  int CountFooErrors(const std::vector<Foo>& foos) {
    int n = 0;  // Clear meaning given limited scope and context
    for (const auto& foo : foos) {
      ...
      ++n;
    }
    return n;
  }
  void DoSomethingImportant() {
    std::string fqdn = ...;  // Well-known abbreviation for Fully Qualified Domain Name
  }
 private:
  const int kMaxAllowedConnections = ...;  // Clear meaning within context
};
class MyClass {
 public:
  int CountFooErrors(const std::vector<Foo>& foos) {
    int total_number_of_foo_errors = 0;  // Overly verbose given limited scope and context
    for (int foo_index = 0; foo_index < foos.size(); ++foo_index) {  // Use idiomatic `i`
      ...
      ++total_number_of_foo_errors;
    }
    return total_number_of_foo_errors;
  }
  void DoSomethingImportant() {
    int cstmr_id = ...;  // Deletes internal letters
  }
 private:
  const int kNum = ...;  // Unclear meaning within broad scope
};

Note that certain universally-known abbreviations are OK, such as i for an iteration variable and T for a template parameter.

  • 일반적으로 널리 알려진 약어정도는 괜찮습니다, 반복문에서의 변수 i와 템플릿 인자의 T처럼 말이죠

 

For the purposes of the naming rules below, a "word" is anything that you would write in English without internal spaces.

  • 아래의 이름 지정 규칙에 따라 "단어"는 내부 공백 없이 영어로 작성되어야 하죠

 

This includes abbreviations, such as acronyms and initialisms.

  • 이는 약어가 포함됩니다, 줄임말이나 두문자어 같이 요

 

For names written in mixed case (also sometimes referred to as "camel case" or "Pascal case"), in which the first letter of each word is capitalized, prefer to capitalize abbreviations as single words, e.g., StartRpc() rather than StartRPC().

  • 대소문자가 섞인 이름(가끔 '카멜 케이스' 또는 '파스칼 케이스'라고도 불리는)에서 각 단어의 첫 글자가 대문자인 경우, 약어를 하나의 단어처럼 대문자로 작성하는 것이 좋습니다. 예를 들어, StartRpc()가 StartRPC() 보다 선호되죠

 

Template parameters should follow the naming style for their category: type template parameters should follow the rules for type names, and non-type template parameters should follow the rules for variable names.

  • 템플릿 인자는 그 범주에 맞는 이름 규칙을 따라야 합니다: 타입 템플릿 인자는 타입 이름에 대한 규칙을 따라야 하며, 논타입 템플릿 인자는 변수 이름에 대한 규칙을 따라야 합니다.

 

working on...

🚧