본문 바로가기
알아두면 손해 없는 정보 저장소

Google C++ Style Guide 2

by anothel 2021. 7. 6.

Google C++ Sytle Guide를 해석해가며 공부한 후 배운 점과 느낀 점에 대해서 서술하려 한다.

 

Background, Goals of the Style Guide


 

Background


C++는 수많은 Google의 오픈소스 프로젝트에 사용되는 주요 개발언어이다. 모든 C++ 개발자가 알고 있는 것처럼 C++는 강력한 기능들이 많지만, C++의 이러한 강력한 기능들은 버그를 일으키기 쉽고, 코드를 읽거나 유지 보수하기 어렵게끔 만드는 복잡성을 갖고 있다.

이 가이드의 목표는 C++를 사용한 개발을 하며 해야 할 것과 하지 말아야 할 것에 대해 아주 자세하게 서술함으로써 복잡성을 관리하기 위함이다. 이러한 규칙은 코드 베이스를 관리 가능한 상태로 유지하면서, C++ 개발자가 생산적으로 개발할 수 있게 한다.

우리는 Style(혹은 읽기 쉬움)을 'C++ 코드를 통제하는 규약'이라고 부른다. Style이라는 말은 사실 좀 부적절하다. 왜냐하면 이러한 규약들은 단지 파일 포맷팅만 하는 것을 넘어서기 때문이다.

구글이 진행하는 대부분의 오픈소스 프로젝트는 이 가이드의 요구사항을 따른다.

이 가이드는 C++ 튜토리얼이 아니며, 우리는 독자가 C++에 이미 익숙해져 있다고 가정한다.

더보기

C++ is one of the main development languages used by many of Google's open-source projects. As every C++ programmer knows, the language has many powerful features, but this power brings with it complexity, which in turn can make code more bug-prone and harder to read and maintain.

The goal of this guide is to manage this complexity by describing in detail the dos and don'ts of writing C++ code. These rules exist to keep the codebase manageable while still allowing coders to use C++ language features productively.

Style, also known as readability, is what we call the conventions that govern our C++ code. The term Style is a bit of a misnomer, since these conventions cover far more than just source file formatting.

Most open-source projects developed by Google conform to the requirements in this guide.

Note that this guide is not a C++ tutorial: we assume that the reader is familiar with the language.

 

Goals of the Style Guide


우리는 왜 이 문서를 만들어야 하는가?

이 가이드가 제공해야 한다고 생각하는 몇 가지 핵심 목표에 대해서 서술하겠다. 해당 목표들은 모든 각각의 규칙에 대한 기저를 이루는 근본적인 이유가 있다. 이러한 이유들을 표면화함으로써, 논의를 바탕으로 하여 우리의 폭넓은 커뮤니티에게 왜 이러한 규칙이 시행되는지, 왜 각각의 결정을 내리게 되었는지에 대한 이유들을 명확히 하기를 바란다. 만약, 각각의 규칙이 어떤 목표로 시행되고 있는지 이해한다면, 규칙이 삭제될 때(몇몇은 그렇게 될 수도 있다.) 혹은 가이드에서 규칙을 변경하기 위한 약간의 분쟁 혹은 대안이 필요할 때 모두에게 명확해질 것이다.

우리가 현재 보고 있는 스타일 가이드의 목표:

더보기

Why do we have this document?

There are a few core goals that we believe this guide should serve. These are the fundamental whys that underlie all of the individual rules. By bringing these ideas to the fore, we hope to ground discussions and make it clearer to our broader community why the rules are in place and why particular decisions have been made. If you understand what goals each rule is serving, it should be clearer to everyone when a rule may be waived (some can be), and what sort of argument or alternative would be necessary to change a rule in the guide.

The goals of the style guide as we currently see them are as follows:

스타일 규칙은 그 임무를 다해야 한다

  • 우리의 모든 엔지니어들이 규칙을 기억하는 것을 요청하기 위함을 정당화할 수 있을 만큼 스타일 규칙의 유익성이 커야 한다. 유익성은 스타일 규칙 없이 우리가 얻을 수 있는 코드 베이스와 비교하여 측정된다. 그래서 매우 해로운 관행에 기댄 규칙을 만약 사람들이 어찌 됐든 사용하지 않는다면, 여전히 작은 유익성을 갖고 있다. 주로 이러한 개념은 우리가 사용하고 있다기보다는 갖고 있지 않다는 것에 대해서 설명하고 있다: 예를 들어, goto구문은 앞으로 나올 여러 개념들을 위반하고 있다. 하지만 이미 거의 사라졌기 때문에 이 가이드에서는 다루지 않는다.
더보기

Style rules should pull their weight

  • The benefit of a style rule must be large enough to justify asking all of our engineers to remember it. The benefit is measured relative to the codebase we would get without the rule, so a rule against a very harmful practice may still have a small benefit if people are unlikely to do it anyway. This principle mostly explains the rules we don’t have, rather than the rules we do: for example, goto contravenes many of the following principles, but is already vanishingly rare, so the Style Guide doesn’t discuss it.

코드를 작성하는 사람 말고 읽는 사람을 위해 최적화해라

  • 우리의 코드 베이스(그리고 대부분의 이미 제출된 컴포넌트)는 상당히 오랜 기간 동안 계속될 것으로 예상된다. 결과적으로, 코드를 작성하는 것보다 읽는 데에 더 많은 시간을 쓸 것이다. 우리는 코드를 작성할 때 쉬운 것보다는, 우리의 보통의 엔지니어가 코드를 읽기, 유지보수 및 디버깅을 위한 최적화를 하기로 결정했다. "읽는 사람을 위한 트레이스 로그를 남겨라"는 특히나 흔한 말이다: 코드에서 일반적이지 않거나, 무언가 갑작스러운 정보(예를 들어, 포인터의 주소 값을 넘길 때)가 나올 때, 코드를 읽는 사람을 위해 포인터의 사용을 순간에 원문의 힌트를 남겨놓는 것은 아주 값지다.(std::unique_ptr은 호출되는 장소에서 소유권 이전을 명료하게 입증한다.)
더보기

Optimize for the reader, not the writer

  • Our codebase (and most individual components submitted to it) is expected to continue for quite some time. As a result, more time will be spent reading most of our code than writing it. We explicitly choose to optimize for the experience of our average software engineer reading, maintaining, and debugging code in our codebase rather than ease when writing said code. "Leave a trace for the reader" is a particularly common sub-point of this principle: When something surprising or unusual is happening in a snippet of code (for example, transfer of pointer ownership), leaving textual hints for the reader at the point of use is valuable (std::unique_ptr demonstrates the ownership transfer unambiguously at the call site).

기존 코드에서 일관성을 유지하라(변하지 마라)

  • 우리의 코드 베이스를 통해 하나의 스타일을 일관되게끔 사용하는 것은 우리가 다른 (더 중요한) 이슈에 집중하게 한다. 또한, 일관성은 자동화를 할 수 있게 한다: 코드 혹은 #include의 포맷을 만들기 위한 툴은 코드가 tooling의 기대에 부합할 때 정삭 작동한다. 여러 상황에서, "일관성을 유지하라" 규칙은 "하나만 골라서 그것에 대해서 걱정하지 마라"에 기인한다; 이 관점에서 유연성을 허락하는 것에 대한 잠재적인 값어치는 사람들이 이 점에 대해서 논쟁을 벌이게 하는 것보다 더 많은 비용을 발생하게 한다.(다른 사람들이 논쟁을 벌이는 것이 유연성을 허락하는 것보다 비용이 덜 드니, 유연성을 허락하는 것이 부정적이다.) 하지만, 일관성에 대한 한계는 존재하고; 명확한 기술적 논쟁이나 장기적인 지시가 없을 때 좋은 최종결정자 역할을 한다. 이러한 상황은 아주 지역적인 것에 적용된다(각 파일, 또는 밀접하게 연관된 인터페이스). 일반적으로 일관성은 새로운 스타일에 대한 유익성 혹은 시간이 지나면서 더 새로워지는 것에 수렴하는 코드 베이스의 경향에 대한 고민 없이, 오래된 스타일의 코드에서 사용하기 위한 타당한 이유로써 사용되어서는 안 된다.
더보기

Be consistent with existing code

  • Using one style consistently through our codebase lets us focus on other (more important) issues. Consistency also allows for automation: tools that format your code or adjust your #includes only work properly when your code is consistent with the expectations of the tooling. In many cases, rules that are attributed to "Be Consistent" boil down to "Just pick one and stop worrying about it"; the potential value of allowing flexibility on these points is outweighed by the cost of having people argue over them. However, there are limits to consistency; it is a good tie breaker when there is no clear technical argument, nor a long-term direction. It applies more heavily locally (per file, or for a tightly-related set of interfaces). Consistency should not generally be used as a justification to do things in an old style without considering the benefits of the new style, or the tendency of the codebase to converge on newer styles over time.

적절한 때에 폭넓은 C++ 커뮤니티와 함께 일관성을 유지하라

  • C++를 사용하는 다른 조직과 함께하는 일관성을 유지하는 것은 우리의 코드 베이스 내의 일관성을 유지하는 것과 같은 이유로 가치가 있다. 만약, C++ standard의 기능이 문제를 해결한다면 혹은 몇몇 관용어(통상적으로 사용하는 코드)가 광범위하게 알려지고 받아들여졌다면 그것을 사용하기 위한 논쟁이 있을 것이다. 하지만, 때때로 C++ standard의 기능과 관용어들에는 결함이 있거나, 우리의 코드 베이스의 필요를 염두에 두지 않고 설계되기도 한다. 이러한 경우 (아래에 설명된 대로) C++ standard를 사용하지 못하게 하거나, 금지하는 것이 적절하다. 경우에 따라서 우리는 탁월성이 인지되지 않았거나, 코드 베이스를 standard 인터페이스로 전환하기에 값이 불충분한 라이브러리보다 직접 개발한 혹은 C++ Standard 위에서 정의된 라이브러리로 만들어진 써드파티 라이브러리를 더 선호할 수 있다.
더보기

Be consistent with the broader C++ community when appropriate

  • Consistency with the way other organizations use C++ has value for the same reasons as consistency within our codebase. If a feature in the C++ standard solves a problem, or if some idiom is widely known and accepted, that's an argument for using it. However, sometimes standard features and idioms are flawed, or were just designed without our codebase's needs in mind. In those cases (as described below) it's appropriate to constrain or ban standard features. In some cases we prefer a homegrown or third-party library over a library defined in the C++ Standard, either out of perceived superiority or insufficient value to transition the codebase to the standard interface.

놀랍거나 위험한 구조를 피하라

  • C++는 한눈에 바라볼 수 있는 것보다 더 놀랍거나 위험한 기능을 가지고 있다. 이러한 위험에 빠지지 않도록 몇 가지 스타일 가이드 제한들이 있다. 몇몇 규칙을 포기하는 것은 종종 프로그램의 정확함을 저해하는 위험을 야기하기 때문 제한에 대한 스타일 가이드의 포기에 대한 높은 기준이 있다.
더보기

Avoid surprising or dangerous constructs

  • C++ has features that are more surprising or dangerous than one might think at a glance. Some style guide restrictions are in place to prevent falling into these pitfalls. There is a high bar for style guide waivers on such restrictions, because waiving such rules often directly risks compromising program correctness.

우리의 일반적인 C++ 개발자가 유지 보수하기에 어렵거나 곤란한 상황에 놓일 구조를 피해라

  • C++는 코드에 포함된 복잡성 때문에 일반적으로 적절하지 않은 기능을 가지고 있다. 그것은 널리 사용되는 코드에서는 까다로운 언어구조를 사용하는 것이 더 적합할 수 있다. 왜냐하면 사용에 따라서 더 복잡한 실행의 유익성들이 급증할 것이고, 코드 베이스의 새로운 부분들과 함께 일할 때 복잡성에 대한 이해를 위한 비용은 발생할 필요가 없기 때문이다. 불확실할 때, 프로젝트 리더에게 요청함으로써 이러한 유형의 규칙들을 포기할 수 있다. 이것은 우리의 코드 베이스를 위해서 특히 중요하다. 왜냐하면 코드의 주인과 팀의 팀원들은 시간이 지남에 따라 변한다: 현재 코드의 일부와 함께 일하고 있는 모든 구성원이 그것을 이해하고 있다 할지라도, 몇몇 이해들은 지금으로부터 몇 년 후까지 유지되는 것에 대해서 보장되지 않는다.
더보기

Avoid constructs that our average C++ programmer would find tricky or hard to maintain

  • C++ has features that may not be generally appropriate because of the complexity they introduce to the code. In widely used code, it may be more acceptable to use trickier language constructs, because any benefits of more complex implementation are multiplied widely by usage, and the cost in understanding the complexity does not need to be paid again when working with new portions of the codebase. When in doubt, waivers to rules of this type can be sought by asking your project leads. This is specifically important for our codebase because code ownership and team membership changes over time: even if everyone that works with some piece of code currently understands it, such understanding is not guaranteed to hold a few years from now.

우리의 규모에 대해서 유의해라

  • 1억 라인 이상의 코드 베이스 그리고 수천 명의 엔지니어들과 함께하며, 몇몇 실수들과 한 명의 엔지니어를 위한 간소화는 많은 비용 지불을 초래할 수 있다. 예를 들어, 전역 네임스페이스 오염시키기를 피하는 것은 특히 중요하다: 수억 개 라인들의 코드 베이스를 가로지르는 이름 충돌은 만약 모든 사람들이 해당 전역 네임스페이스에 데이터를 넣었을 경우, 처리하기 어렵고 피하기도 어렵다. 
더보기

Be mindful of our scale

  • With a codebase of 100+ million lines and thousands of engineers, some mistakes and simplifications for one engineer can become costly for many. For instance it's particularly important to avoid polluting the global namespace: name collisions across a codebase of hundreds of millions of lines are difficult to work with and hard to avoid if everyone puts things into the global namespace.

필요에 의해서 최적화해야 함을 인정해라

  • 성능 최적화는 때때로 필요하고 적절할 수도 있다. 심지어 그들은 이 문서의 다른 개념과 충돌을 일으킬 수도 있다.
더보기

Concede to optimization when necessary

  • Performance optimizations can sometimes be necessary and appropriate, even when they conflict with the other principles of this document.

이 문서의 의도는 합리적인 제한을 동반한 최대한의 안내를 제공하기 위함이다. 늘 그렇듯, 보통의 감각과 좋은 맛은 만연해야 한다. 이에 따라 우리는 개인적인 선호나 팀의 규약뿐만 아니라 전체적인 Google C++ 커뮤니티에서 이미 세워진 규약에 대해서 참조한다. 기발하거나 흔치 않은 구조를 사용함에 있어서 의심을 갖고 주저해라: 금지 규정에 대한 부재는 통과하기 위한 라이선스와 같지 않다. 당신의 판단을 사용하고, 확신이 든다면, 프로젝트 리더에게 새로운 규정을 넣는 것에 대해서 주저 없이 요청해라.

더보기

The intent of this document is to provide maximal guidance with reasonable restriction. As always, common sense and good taste should prevail. By this we specifically refer to the established conventions of the entire Google C++ community, not just your personal preferences or those of your team. Be skeptical about and reluctant to use clever or unusual constructs: the absence of a prohibition is not the same as a license to proceed. Use your judgment, and if you are unsure, please don't hesitate to ask your project leads to get additional input.

 

중간 마무리


여러 명이 하나의 애플리케이션에서 다양한 기능을 나눠서 개발을 할 때, 정해진 코딩 스타일 없이 개발을 하다 보니 각자가 추구하는 스타일로 개발을 했다. 그런데 아무리 기능을 나눠서 개발했다 할지라도 서로의 코드를 읽어야 할 때가 있었는데, 이때 서로의 스타일이 다르다 보니 이해하는 데에 난해한 부분이 있었다. 아마 이때부터 코딩 스타일에 대해서 고민했던 것 같다.

내가 작성한 코드는 해당 코드를 읽고 유지보수 혹은 추가 개발을 할 다음 사람과의 대화라고 생각한다(아직까지 그 사람은 거의 대부분 나이긴 하다.). 그런데 대화를 함에 있어서 일관된 규칙이 있다면 그것을 이해하는 데에 들이는 시간보다 다른 것에 더 많은 시간을 투자할 수 있을 것이다.

Google은 내가 근무했던 회사들보다는 확실히 큰 집단인 것 같다(명확하다.). 수 억 라인의 코드와 수 천명의 엔지니어. 아무래도 거대한 집단이다 보니 일관된 코딩 규칙이 반드시 필요했을 것이다. 그 거대한 집단은 대체 어떠한 코딩 규칙을 정해놓았는지 훑어보고, 내가 작성한 코드를 읽을 나 자신을 위해서 나에게 적용할 수 있도록 노력해봐야겠다.

 

출처: https://google.github.io/styleguide/cppguide.html 및 내 생각 그리고 영어사전

728x90