함수의 리턴값에 static 이 붙을 경우

rootuser7의 이미지

아주 기초적인 내용인데 좀 혼돈이 되는 부분이 있어서 문의 드립니다.
변수의 scope를 나타내는 기억클래스 중에서 static에 관한 문의입니다.
외부 static을 변수명 앞에 붙이면, 그 변수는 해당하는 모듈 파일 내에서만 유효한 것으로 알고 있습니다.
예를 들면…
aaa.c 파일에서,

static int variable;
static int variable_aaa;

bbb.c 파일에서,

static int variable;

라고 각각 선언되어 있다고 합시다.
위에서 aaa.c에서 선언된 variable 변수는 bbb.c에서 선언된 variable과 다르다는 것입니다.
또한 aaa.c파일에서 선언된 variable_aaa는 aaa.c파일 내에서만 사용가능하고,
bbb.c등의 다른 파일에서는 사용이 불가능합니다.

그렇다면, 함수의 경우에는 어떻게 되는지요 ? =>[질문 내용]
예를 들어서…
aaa.c파일 내에서
static int Function( int aaa)
{

}
라고 선언된 함수가 있다고 할 경우에…
이 함수의 용도는 어떻게 되는가요 ?
즉..static와 붙어 있을 경우와 안 붙어 있을 경우는 어떤 차이가 있는가요 ?

답변 주시면 감사하겠습니다.

coremaker의 이미지

반환되는 타입(int)에 대한 static 이 아니라..
함수에 적용되는 static이 되는 것입니다..
일반적으로 함수는 호출될 당시에 물리메모리에 적재되어 실행됩니다..
미리 적재되지 않죠.. static 선언을 하면
프로그램이 실행되면서 당장 쓰지 않아도 물리메모리에 적재됩니다..
커널 내에서 이런 코드 많이 사용하구요..
이유는 로딩속도에 민감한 경우에 이런 부분에 대한 해결책 중 일부로 사용합니다..

익명 사용자의 이미지

이건 아니죠~
사용자 프로그램의 코드가 메모리 적제되는 시기는 OS가 결정합니다. 보통 프로그램코드가 처음 실행되는 시점에 적제하기 시작하죠. 적제되는 단위 또한 OS가 결정하구요. 보통 메모리 페이지 크기로 되는걸로 알고있습니다.
함수에 static 이 붙으면 아래에서 설명된 것 처럼, 변수의 그것처럼 같은 파일에서만 유용한걸로 알고있습니다. 만약 다른파일에서 호출하려면 함수포인터같은 다른방법을 이용해야 합니다.
커널에 static 함수 선언이 많은 이유는, c 로 모듈화, 객체화를 많이 했기 때문입니다. c++에서 흔히 사용하는 정보의 숨김, 등의 이유겠죠, 참고로 커널의 함수의 프로그램코드는 항상 메모리상에 존제하게 됩니다.

coremaker의 이미지

죄송합니다..
전에 이거 가지고 친구랑 한참 이야기하던 것에서
뒷부분을 하얗게 까먹었군요..

수정합니다..
흔히 다른 파일에 있는 함수나 변수를 사용할 때..
export 해서 쓰는데..

이걸 못쓰도록 하는 방법이 static 이였던 것이 맞군요...
물론 함수에서만..

위에 오답에 대한 설명은 inline 함수로 대체해야겠네요..
지적 감사합니다..

익명 사용자의 이미지

inline 함수는 "호출" 되는 함수가 아닙니다.
소스 상에서 inline 함수를 호출하는 부분에 그대로 "삽입"이 되는 함수입니다.
메모리에 해당 코드가 적재되는 것과 inline 함수와는 아무런 관계가 없습니다.

예를 들어서,

void foo(void) { do something useful; }

void bar(void)
{
routine 1;
foo(); /* <1> */
routine 2;
foo(); /* <2> */
routine 3;
foo(); /* <3> */
}

과 같은 코드에서

1. foo() 가 inline 함수일 때 컴파일러는 bar() 를 아래와 같이 해석합니다 :

void bar(void)
{
routine 1;
{ do something useful; };
routine 2;
{ do something useful; };
routine 3;
{ do something useful; };
}

2. foo() 가 inline 함수가 아닐 때 컴파일러는 bar() 를 아래와 같이 해석합니다 :
void bar(void)
{
routine 1;
call foo();
routine 2;
call foo();
routine 3;
call foo();
}

따라서 어떤 함수를 inline 시켜서 여러번 호출하게 되면, 그 소스파일을 컴파일한 object 파일의 크기가 커집니다.

참고로, inline 키워드를 굳이 주지 않더라도 gcc 의 최적화 레벨을 높이게 되면 static 으로 선언된 함수들은 알아서 inline 을 시키게 됩니다.

inline 함수를 작성하실 때 주의하실 것은, inline 함수와 그 함수를 호출하는 루틴은 동일한 소스 파일에 모두 들어 있어야 한다는 것입니다. 그렇지 않을 경우에는 inline 되지 않습니다. 심지어 inline 키워드를 명시적으로 사용하더라도 inline 함수가 호출하는 루틴과 다른 소스 파일에 들어 있을 경우에는 inline 되지 않습니다. 컴파일러가 그 함수의 내용을 알 수 없기 때문이죠. 그렇다면 링커가 그 작업을 해 주면 되지 않겠느냐는 생각을 할 수도 있는데, 그 작업을 해 주는 링커가 있다는 이야기는 들어 보지 못했으며, 구조적으로 불가능(억지로 끼워 맞추면 가능하도록 링커를 만들면 가능이야 하겠지만 그 오버헤드와 복잡함을 생각할 때 불가능하다는 이야기입니다)합니다.

좀 더 쉽게 설명하자면,

1. foo() 가 inline 될 수 있는 경우 :
- foo() 와 bar() 모두 a.c 에 있는 경우
2. foo() 가 inline 될 수 없는 경우 :
- foo() 는 a.c 에, bar() 는 b.c 에 있는 경우

Necromancer의 이미지

c++이나 자바에서 쓸 수 있는것으로 알고 있습니다. c는 모르겠군요.

클래스내 함수(정확히 말하자면 메소드죠)에 저거 쓰면 인스턴스없이 클래스명갖고 바로 호출가능하죠.

class CTest {
    ....
    static void function(void);
    ....
}

이런 코드일 경우 아래와 같은 식으로 호출되죠.

main() {
    ...
    CTest.function();
    ...
}

Written By the Black Knight of Destruction

Written By the Black Knight of Destruction

jick의 이미지

이건 class에서 instance method와 class method를 구분하기 위해 사용하는 static이고, 원래 C에서 쓰던 static 함수와는 다른 의미로 쓰인 것입니다.

익명 사용자의 이미지

CTest.function(); -----> CTest::function();

정건호의 이미지

함수리턴값에 static 이 있으면 해당파일에서만 유효한걸로 알고 있습니다.

즉 외부파일 에서는 함수를 호출 할수가 없고 내부파일에서만 호출가능하겠지요.

익명 사용자의 이미지

윗분 말씀대로 변수에 static 붙이는 경우와 동일합니다. 하나의 소스 파일을 일종의 모듈로 생각하고, 모듈 내부에서만 사용할 함수, 변수 등에 static 을 붙여서 사용하는 것입니다. C++/자바 등의 private 키워드와 비슷한 의도를 가지고 사용하는 겁니다. 물론 C++/자바에서는 소스 파일이 아니라 클래스 단위로 접근을 제한하지만 의도는 같습니다.

바라미의 이미지

정확히 말하자면, 해당 함수를 링커에 알리지 않는 것입니다. 그렇게 되니, 다른 모듈(즉 다른 소스파일) 에서 해당 함수를 쓰려고 해도 링크할수가 없으니 사용하지 못하는것이 되는거지요.

Fe.head의 이미지

오.. 그렇군요. 좋은 팁 감사합니다.
-----------------------
과거를 알고 싶거든 오늘의 네 모습을 보아라. 그것이 과거의 너니라.
그리고 내일을 알고 싶으냐?
그러면 오늘의 너를 보아라. 그것이 바로 미래의 너니라.

고작 블로킹 하나, 고작 25점 중에 1점, 고작 부활동
"만약 그 순간이 온다면 그때가 네가 배구에 빠지는 순간이야"

댓글 달기

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