static function이란?

gnugpl의 이미지

static function에 대해서 자세히 알고 싶습니다.
일반적으로 C에서 파일내에서만 참조하려는 글로벌 function 이나 변수는
static으로 선언합니다.
물론 static이라는 특성을 가진채..

static은 한번만 생성되는것으로 알고 있습니다.

그렇다면 파일내에서 satic으로 선언하는것은 어떠한 장점이 있는지요?
메모리 관점에서 질문을 드립니다.

그리고 C++에서경우 static 멤버함수를 호출시에는
레퍼런스를 가지고 있지 않더라고 하더라도 직접 다른 클래스에 포함되어 있는
멤버 함수를 호출할수 있습니다.

다음과 같이 B클래스 내부에서 A::function()
같이 호출할수 있는데
이러한 점은 어떠한 메모리 관점으로 볼수 있는지요?

마지막으로 static 함수를 합리적으로 쓸수 있는 지침이 있는지요?

부탁드립니다.

송지석의 이미지

질문 내용을 다 보지는 않고 답변을 드리는거네요.

저도 전문가라고는 할 수 없지만

static을 쓰는 경우의 장점은 다른 소스 파일에서 같은 이름으로 함수를 만들었을 때도 제대로 동작하는 거지요.

static으로 선언해놓으면 그 파일 내에서만 사용하는 것으로 되거든요.

그래서 외부에 인터페이스가 노출되지 않습니다.

a.c에 static void my()라는 함수가 있었는데
소스를 짜다가 같이 사용하는 b.c에도 static int my()라는 함수를 만들어 쓰더라도 이름이 같아서 링커 에러나 이상한 동작을 하지 않게되죠.

틀린 부분 있으면 지적해주세요.

bugiii의 이미지

안녕하세요?

먼저 static 함수앞에 붙은 경우에는 윗분의 말씀대로 우선적으로 스코프 한정자로써의 역할을 하게됩니다. 원래 c/c++에서는 같은 이름의 구분자는 전 프로그램에 걸쳐서 단 하나만을 허용하는 것이 원칙이지만 각 유닛(소스)별로 static이 붙은 함수는 별개로 취급받게 됩니다. 그리고 그 함수는 그 유닛에만 적용되는 것이고 절대 다른 곳에서 볼 수가 없게 됩니다. (직접적인 호출이 안된다는 것) 하지만 이것도 함수 포인터를 사용해서 어찌어찌하면 호출할 수 있겠죠. 어차피 이름만 공개안된 함수이니까요.

예를 들자면, 헤더파일에 일반 함수의 본체가 들어가는 경우 (대부분 잘못된 것이지만) 보통의 경우 링크과정에서 에러가 나겠지만 static이 붙은 함수 본체는 각 유닛별로 별개의 함수로 취급받으므로 통과할 것입니다. 이건 meyer EC 에 있는 구형 컴파일러의 inline 함수 취급법과 유사합니다. 이것이 예상치 못한 이상한 동작을 할 수도 있는데 예를 들자면 그 함수안에 static 변수가 있다고 하면 의도하지 않는 결과가...

변수의 경우에는 그 함수에 적용되는 의미가 마찬가지로 적용됩니다. 예를 들자면,

static char* __file__ = __FILE__;

같은 문장이 각 유닛에 각각 포함되어있다면 각 유닛은 자신의 파일 이름을 가지는 __file__ 문자열 변수를 가지게 됩니다. 소스상의 이름은 같지만 완전히 다른 곳을 참조하는 다른 변수가 됩니다. (옛날에는 메모리가 좀 모자라는 경우에 디버깅용 메시지를 출력할 때 조금이라도 메모리를 줄여보고자 사용하던 기법이기도 하구요. __FILE__ 이라는게 꽤...) 소스 파일별로 큰 괄호 {} 가 있다고 생각할 수도 있겠습니다.

일반 변수 (함수 바깥) 나 함수의 static 장점은 모듈단위의 스코프를 지원한다는 것 외에 메모리상의 장점은 없다고 생각됩니다.

멤버 함수와 멤버의 경우에도 유사하게 그 클래스에서만이라는 한정이라는 것이 위 경우와 유사합니다. 하지만, 이 경우는 오직 하나만이라는 것이 진짜로 적용되는 것입니다. (누군가가 static 이라는 키워드를 여기에 사용하는 것을 뭐라고 하던걸로 기억을...)

static 멤버는 아시다시피 그 클래스에서 (그 클래스의 인스턴스들 뿐만 아니라 자손들의 인스턴스를 모두 포함해서) 딱 하나만 존재하는 것이므로 메모리상에 딱하나 main 전에 (하지만 순서는 누구도 모르는) 생성되고, 클래스의 인스턴스가 만들어질 때마다 추가되는 메모리가 없습니다. 사용 예는 그 클래스가 몇개나 만들어졌나 같은 것 등에 이용될 수 있습니다.

static 멤버 함수는 비슷한 의미로 사용됩니다. 그리고, 이것이 public 으로 선언되면 다른 멤버처럼 어디서나 호출되고 하는 것은 다른 멤버와 마찬가지입니다. b 클래스에서 a 클래스의 static 멤버 함수를 호출할 수 있는 것이 아니라 누구나 호출할 수 있는 일단은 멤버 함수인 것이겠죠.

그리고, 함수를 (어떤 함수든지간에) 메모리 입장에서 본다는게 의미가 있는지는 모르겠습니다. 자기 수정 코드가 아닌 이상에는 일반이든 멤버든 가상이든 static 이든 일단 본체는 메모리 어디엔가에 고정되어 있긴 한거니까요. 다만, 그 불려지는 당시의 상황이 어떤 함수를 부를 것인가가 (고정되어 있는 것인지 아니면 동적으로 해결해야 하는 것인지가) 틀릴 뿐이라고 생각합니다.

하여튼 이것이 필요한 경우가 있는데, 예를 들면, 클래스 본체를 숨기고 인터페이스만 외부에 알릴 경우 실제 본체를 생성하는 함수를 static 클래스 멤버 함수로 하면 namespace 같은 효과를 볼 수도 있고, c 인터페이스인 윈도우 시스템이나 쓰레드 같은 것을 클래스로 감쌀 때 콜백이나 시작함수를 이것으로 지정해서 c 측에서 알 수 없는 this 콜을 간접적으로 수행하게 할 수도 있습니다. (물론 인자로 다들 염두해 두는 context 같은게 제공될 경우)

그외에 singleton 을 간단하게 구현할 경우에 요긴하게 static이 사용되기도 합니다.

이런 예제들은 meyer MEC 에 몇개가 있습니다.

static 이 없으면 안되는 경우가 분명히 있습니다. 그 의미하는 바는 정확한 문서나 텍스트를 참고하셔야 하겠습니다. 그리고, 그 적절한 사용예는 직접 구현에서 체득하는 것 밖에는...

그럼, 이만...

pynoos의 이미지

첨언하자면,

저의 경우 C 모든 함수는 static 으로 작성합니다. 그리고 외부에서 사용하는 것만 static을 제거합니다. 그렇게 제거한 것은 header에도 추가합니다.

인터페이스측면에서, 모든 함수를 밖으로 내놓는 다는 것은 혼란을 가져올 뿐이며, 이름공간을 낭비하는 일이 됩니다.

C++의 경우에 대해 static 멤버 함수는 instance없이 접근이 가능한 이유는 static 아닌 멤버함수와는 달리 암묵적인 this pointer가 넘어가지 않기 때문입니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.