본문 바로가기

IT

[C#] 코딩컨벤션, linux_kernel_coding_style vs camelCase vs PascalCase


안녕하세요, 개발자 윤진입니다.


코더로서 개발을 막 시작하고 얼마 후-

코딩컨벤션으로 개발자들끼리 핏대를 세워가며 언성을 높이는 것을 목격하였습니다.

당시에는 '간단한 함수의 경우 헤더에 함수를 정의해도 되는가'라는 주제로 피튀기게 양 진영이 거세게 싸웠는데요,

이후에 파일명, 함수명, 변수명의 이른바 '온갖 것에 대한 작명'에 대한 혈투가 개전되어, 모두가 가열차게 답메일을 보내 메일함이 폭발한 적이 있습니다.

그리고, 프로그래밍에서는 '작명'이 가장 어렵다는 결론을 내리며 훈훈하게 마무리되었죠.

'작명'이 가장 어렵다는 결론은 아직까지 유효합니다. :)

함수나 변수의 역할을 그 이름만으로 정확하게 파악할 수 있게 만드는 것은 프로그래밍의 영역이라기 보다는 예술의 영역에 가깝습니다.

그리고 이 영역에서 프로그래머의 센스와 자질이 드러나죠.


사실, 코딩컨벤션은 코드의 성능이나 안정성과는 거리가 멀지만,

코드독해에 직접적인 영향을 주는 요소입니다.

눈에 익숙하게 들어오는 코딩컨벤션이 아무래도 빨리 읽히는 법이죠.

그렇기 때문에 개발자들이 그렇게나 코딩컨벤션에 열을 올립니다.

코드는 짜고 난 뒤에도 수많은 개발자들에게 되풀이되며 읽히기 때문에, 개발자들의 원활한 정신상태를 위해 코딩컨벤션을 제대로 지켜줘야합니다.

개인적으로 일관성없는 코딩컨벤션으로 점철된 코드를 보면, 두통이 생기며 고치고 싶다는 욕망이 생깁니다.


C언어로 개발을 할 때는 기본적으로 linux_kernel_coding_style을 따랐습니다.

리눅스 스타일 문서에서는 작명에 대한 기준도 볼 수 있습니다.


4. 이름짓기 


C 언어는 간소한(Spartan) 언어이므로, 이름짓기 규칙도 이를 따라야 한다. Modula-2 나 파스칼 프로그래머와는 달리, C 프로그래머들은 ThisVariableIsATemporaryCounter 와 같은 귀여운(?) 이름을 사용하지 않는다. C 프로그래머들은 "tmp" 와 같이, 쓰기 쉽고 이해하기도 그리 어렵지 않은 이름의 변수를 사용할 것이다.

하지만, (대소문자를 섞어쓰는 것은 보기 안좋지만) 전역 변수에 대해서는 반드시 충분한 설명이 될 만한 이름을 붙여야 한다. 전역 함수의 이름을 "foo" 라고 짓는 것은 범죄 행위(shooting offense) 이다 (FIXME!)

전역 변수는 (정말로 필요한 경우에만 사용하자) 충분한 설명이 될 만한 이름을 가져야 하며, 이는 전역 함수에 대해서도 마찬가지이다. 만약 활동 중인 사용자의 수를 세는 함수를 작성했다면 이 함수의 이름은 "count_active_users()" 혹은 이와 비슷한 형태가 될 것이며, "cntusr()" 과 같은 형태가 되어서는 안 된다.

함수의 이름에 타입을 포함시키는 방식 ("헝가리안 표기법"이라고 한다) 은 멍청한 짓이다. 컴파일러는 타입을 알고 체크할 수 있으며, 이러한 표기법은 단지 프로그래머를 혼동스럽게 할 뿐이다. MicroSoft 에서 버그가 많은 프로그램들을 만들어 내는 것을 보면 당연하다.

지역 변수는 짧게 핵심만을 나타내는 이름을 사용한다. 만약 어떤 임의의 정수 루프 카운터가 필요하다면 그 이름은 "i" 가 될 것이다. 이를 "loop_counter" 라고 표기하는 것은 오해를 살 만한 여지가 없는 경우에는 생산적이지 않다. 마찬가지로, "tmp" 일시적인 값을 가지는 어떤 타입의 변수에도 사용될 수 있다.

혹시 여러분이 지역 변수 이름이 많아져 뒤섞이지 않을까 걱정하고 있다면, 여러분은 함수-성장-호르몬-불균형 증후군이라는 다른 문제를 가지고 있는 것이다. 6장 (함수) 부분을 보기 바란다.



C언어를 사용할때 대문자는 #define문 정도에서만 사용하였습니다.

온갖 이름은 소문자와 '_'(언더스코어)의 조합만으로 아름답게 명명되었죠.

함수나 변수도 그 적용범위에 따라 제각각의 작명법이 있었지만 모두 소문자와 '_'만으로도 충분했습니다.


그렇지만, C#의 세계에서는 C언어의 linux_kernel_coding_style은 '읽기 쉽지 않은' 코딩 컨벤션의 부류에 들어가더군요.

그 동안 줄곧 언더스코어의 세계에서 행복하게 살았는데,

C#의 세계에서는 (상대적으로 그리고 개인적으로) 읽기 번거로웠던 camelCase와 PascalCase의 세계에서 살아나가야 합니다.

이 세계에는 '_'는 죄악과 마찬가지입니다.


Capitalization Rules for Identifiers

To differentiate words in an identifier, capitalize the first letter of each word in the identifier. Do not use underscores to differentiate words, or for that matter, anywhere in identifiers. There are two appropriate ways to capitalize identifiers, depending on the use of the identifier:

  • PascalCasing

  • camelCasing


Microsoft의 코딩컨벤션 문서에서는 camelCase와 PascalCase를 읽기 쉽다고 콕 찝어 표현합니다.

Microsoft의 입장과 같은 맥락에서,

1) '_'로 단어간 구분한 문장과,

2) 대문자로 구분한 문장을 두고,

어느 쪽이 빨리 읽히는지 실험한 자료도 읽은 기억이 납니다.

그 때는 대문자로 구분한 문장이 더 빨리 읽혔기에 자바에서 camelCase를 선택했다고 주장하는 글을 읽은 기억이 있습니다.


하지만, 비교적 최근인 '10년에 Eye tracking으로 독해속도와 오타교정속도을 조사한 논문[각주:1]이 나옵니다.

이 논문은 과거에 읽었던 내용과는 상반되는 결론을 보여주는데요.

독해속도에서 with_underscore 표기법이 withoutUnderscore 표기법보다 무려 20% 정도나 빠르다고 합니다.

오타교정속도도 독해속도가 빠른 with_underscore 방식이 더 빨랐습니다.

Microsoft가 어떤 기준으로 camelCase나 PascalCase가 더 읽기 쉬운 코딩컨벤션으로 선택했는지 모르겠지만,

분명, 치밀하게 고민하고 결정했다고 생각합니다.


어느 코딩컨벤션이 더 좋든, 기본적으로 코딩컨벤션은 기존 코드에서 사용한 코딩컨벤션을 따라주는게 맞습니다.

만약 기존 코딩컨벤션이 정 맘에 안들면, 

해당 커미터들과 치열하게 싸워 결론을 내린 후,

코드 전체에 동일한 코딩컨벤션을 유지시켜면 됩니다.

실제로 이런 번거로운 과정을 거쳐, 자동화툴로 코딩컨벤션을 바꿔서 diff가 수만줄 남긴 기억이 있습니다.


어쨌든, C#의 세계에 발을 담그는 지금부터,

camelCase와 PascalCase에 적응하고자 합니다.

머리가 굳었으니 그만큼 시간이 더 걸리겠네요.


그럼 좋은 하루 보내세요.



  1. Bonita Sharif and Jonathan I. Maletic, "An Eye Tracking Study on camelCase and under_score Identifier Styles", 2010, Kent State University [본문으로]