extern 사용에 대한 의견을 듣고 싶습니다.

hahaite의 이미지

안녕하세요.

저는 코딩할 때 다른 파일의 함수를 사용하고자 하면 #include "~~.h" 하여
해당 함수를 쓰자입니다.

extern 으로 함수 갖다 쓰는걸 그닥 안좋아하는데요.

옆 동료의 코드를 보니 가뿐하게 extern 을 사용하여 함수를 갖다쓰더군요.

그래서 extern 을 찾아봤는데 어디서도 쓰지 말자는 내용은 없더라구요.
옛날에 어디선가 본 것 같은 느낌이 살짝 드는 것 같기도 한데... ㅡㅡa

걍 쓰면 되는데 제가 오버하는 걸까요?

고수분들의 조언 부탁합니다.

그럼, 즐거운 하루되세요. ^^

semmal의 이미지

왜 안좋아하게 되었는지 알 수 있을까요?

------------------------------
How many legs does a dog have?

hahaite의 이미지

그러게요. 그게 저도 궁금해요. ^^;;

^^

semmal의 이미지

제 생각에 사람들이 무언가를 싫어할 때는 크게 두 가지 이유가 있는 것 같습니다.
하나는 잘 모르니 일단 부정하는 것이고, 아니면 더 좋은 수가 있기 때문에 싫어하는 겁니다.

확실히 더 좋은 수가 있다면 안써도 됩니다.
그러니 잘 몰라서 싫다면, 더 좋은 수가 생길 때까지는 꾸준히 써보는게 좋다고 봅니다.

------------------------------
How many legs does a dog have?

세벌의 이미지

전역변수를 남발하면 안 된다는 건 많이 봤지만 extern 쓰지 말란 얘기는 못 들어봤네요.

hahaite의 이미지

전역변수 가져다 쓸 때 extern 의 거부감이 생긴걸까요? ㅋ~

^^

ymir의 이미지

임의의 위치에 extern 으로 함수를 call 해서 쓴다는 얘기는..
코드의 모듈 구성이 제대로 분할되어 있지 않다는 뜻도 될 수 있을 것 같습니다.

모듈을 나누고 상호 참조 관계를 정의해서 레이어를 구분하면, 굳이 extern 으로 쓸 이유가 없을텐데요.
말 그대로 임시로 call 해서 쓰고, 나중에 리팩토링 한다면 모를까..
일상적으로 extern 으로 call 해서 쓴다면 소스가 커지고 양이 많아질 때..
magic number 처럼, 관리가 어려울 수 있습니다.

장기적으로 관리가 필요한 소스라면, 적절히 모듈별로 헤더로 빼주는게 나을 것 같습니다.

전역변수던 함수던 extern 으로 마구 가져다 쓰는거, 코드 수정할 때 관리포인트가 늘어나는 거라서...
코드가 지저분해지고, 관리하기 힘들어집니다.

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

ohdh2003의 이미지

생각해보세요. 인수가 아주 많이 들어있는 함수가 (FORTRAN만큼 복잡하게 만들지는 않겠지만...) 있는데 어쩌다가 그 함수를 고쳐야 했어요. 그래서 또 불행하게도 인수중 몇개가 늘어 났거나 몇개가 없어졌다고 쳐봐요. 그럼 extern으로 선언된 곳을 찾아서 일일이 고쳐줘야 하겠죠. (물론 grep을 쓰면 쉽게 찾을 수 있겠지만... 근데 모듈별로 디렉토리로 쪼개 놨다면... 낄낄낄.) 그런거 틀릴 경우 컴파일러가 말해주면 좋은데 C 컴파일러는 그렇게 친절하지 않을 껄요. 해서 컴파일 됬다고 실행했어요. 첫눈에는 별 문제 없을 것 처럼 보이지만... 고쳤던 그 함수를 실행하려고 하는 순간 근데 그게 하필이면 프로토타입을 잘 못 적어서 다른 인수가 전해 질 때 거의 틀림없이 세그멘테이션 폴트가 생기죠.

It is better--much better--to have wisdom and knowledge than gold and silver [Proverbs 16.16]

semmal의 이미지

안쓰는게 아니라 필요할 때만 쓰는게 맞습니다.
가끔 사람들이 너무 극단적인 선택을 당연하게 생각하는데,
전혀 안쓰는 것도 답이 아니고, 무조건 쓰는 것도 답이 아닌 건 당연한 문제입니다.
extern이든 goto든 singleton이든 쓸만한 곳에 쓰면 아무 문제가 없습니다.

가능하면 피할 방법을 찾는 것은 당연히 좋은 버릇이지만,
누가 봐도 한눈에 왜 썼는지 알 수 있는 곳에 쓰는 건 전혀 나쁜 버릇이 아닙니다.
문법적으로 가능한 기능은 써도 되는 상황이 있기 때문에 존재하고 있는 겁니다.

------------------------------
How many legs does a dog have?

oosap의 이미지

말씀하신 목적이라면 저도 extern 키워드를 쓰는 건 비추 입니다. 저도 같은 습관이 있고요.

아래 포스트를 보면 함수는 단순히 extern 만을 주었다고 해서 달라지는 것은 없다는 것을 알 수 있습니다.
변수는필요하겠어요 ... 안쓰면 중복선언되니까요
http://kldp.org/node/121134

예전에 어느 한심한 사람이 위와 같은 질문을 해서 쓰레드가 생긴 적이 있어요.
이번 논의하고 직접 관련은 없지만 extern 키워드의 정말 필요한 용도를 알 수 있는 것 같아요.
그러니까 extern "C" 와 같이 사용되는 경우가 있는데 이런경우는 반드시 필요하죠.
변수에도 필요하고요
말씀하신 용도(함수)로는 쓸 필요 없다는데 1표 던지고요..

한심하다고 했던 사람이 저예요. 제가 이름을 쓰는게 싫어서 아이디를 새로 만들었습니다. ^^;

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3225.pdf

저는 하숩니다만 예전쓰레드가 생각나서 몇자적어봅니다

위 쓰레드에서 언급된 스펙이예요.. 혹시 도움이 되실지도..

Thanks for being one of those who care for people and mankind.
I'd like to be one of those as well.

grassman의 이미지

C 언어 자체가 함수 호출 전에 prototype을 선언하도록 하고 있기 때문에 prototype 선언에 extern을 붙이는 건 사족과 같은 존재입니다. 변수의 경우에는 extern 선언을 하지 않으면 참조할 방법이 없으니 반드시 써야 하지만 prototype이 있는 함수 호출에서는 extern은 쓰지 않아도 된다고 봅니다. (prototype을 header가 아닌 source code 내에서 선언하는 바람에 원래 함수와 선언이 달라지는 경우는 human error라고 봐야겠지요. 그건 extern과 관계도 없고 잘못된 프로그래밍 습관이 낳은 오류가 되는 것이니 말입니다)

P.S. extern "C" 같은 특수 선언의 경우는 예외입니다.

P.S.2. 다시 한번 강조하자면 함수의 경우에는 extern으로 쓴 곳에 extern을 빼도 완전히 동일하게 동작합니다. prototype으로 인식하기 때문입니다.

P.S.3. 계륵 -> 사족으로 고쳤습니다. 써놓고 보니 이상해서 다시 보니 잘못 썼군요.

ymir의 이미지

@grassman // 원 글의 문제는 prototype 선언시 extern 표시 여부가 아니라..
다른 모듈 내의 함수를 참조하기 위해 임의로 소스 코드 내에 prototype 을 적고 가져다 쓰는 것을 지적하는 것으로 보입니다.

다른 소스 파일의 함수를 참조하기 위해 prototype 을 적으면서 소스 파일 내에 extern 를 써주는 이유는..
컴파일러가 아닌 사람을 위한 것도 있습니다.
전역변수의 경우와 비슷한 문맥으로, 이 함수는 현재 같은 소스 파일이 아닌 다른 소스 파일에 있다는 걸 표시하는 거죠.
헤더로 몰아 넣으면 그때에는 정말로 extern 키워드가 무의미해지죠.

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

grassman의 이미지

헤더에 prototype을 쓰고 그 헤더를 원래 소스가 include 하도록 하면 나중에 함수의 parameter가 바뀌었을 때 header의 prototype까지 바꿀 수 밖에 없으므로 함수의 parameter를 잘못 호출하는 사태는 막을 수 있습니다.

다른 소스내에서 임의로 extern으로 선언할 경우 컴파일러가 오류를 잡아주지도 못할 뿐 아니라 사람이 함수 호출 부분을 전부 교체해 주는데 실수라도 하면 버그가 하나 더 추가됩니다. (컴파일러가 잡아주는 경우와는 다르게 사람은 실수할 수 있습니다) 단순히 디버깅 목적의 임시 코드에 extern으로 가져다 쓰는 건 문제가 안되겠지만 실제 사용할 코드에 extern 함수 호출은 명백히 안 좋은 습관입니다.

P.S. 열심히 써놓고 보니 같은 내용으로 답글을 쓰셨군요. 삭제하는 기능이 없어서 그냥 남겨둡니다.

ymir의 이미지

넵 맞습니다.

전역 변수던 함수던 맘대로 extern 으로 끌어다 쓰는거 아주 좋지 않은 습관이고..
정 부득이 하게 써야 하는 경우, 함수 prototype 에 extern 을 적어줘서 (설령 사족이라 할지라도)..
문맥상 다른 파일에 본체가 있음을 표시해 주는게 낫다는 뜻이었습니다.

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.