지역영역에서 전역영역접은은 어떻게하죠?

sala123의 이미지

int q ;

void vvv()
{
int q ;
//전역변수q에 접근하려면 어떻게해야하나요.......
}

C++에서는 ::q로 한거 같은데 gcc에서 잘 안되서요.

그리고 하나더 질문이 있는데요.
a.c
-------------
int qqq = 111 ;
int main() {... }
-------------
로 qqq를 선언하고!

bc
-------------
int qqq ;
-------------

이렇게 두개의 파일에 전역변수 qqq를 모두 선언했는데도 컴파일에러가 발생하지 않는 이유는 무엇인가요...

wafe의 이미지

sala123 wrote:
int q ;

void vvv()
{
int q ;
//전역변수q에 접근하려면 어떻게해야하나요.......
}

C++에서는 ::q로 한거 같은데 gcc에서 잘 안되서요.

원래 C에서는 안되는 것으로 알고 있습니다.

Quote:

그리고 하나더 질문이 있는데요.
a.c
-------------
int qqq = 111 ;
int main() {... }
-------------
로 qqq를 선언하고!

bc
-------------
int qqq ;
-------------

이렇게 두개의 파일에 전역변수 qqq를 모두 선언했는데도 컴파일에러가 발생하지 않는 이유는 무엇인가요...

두 qqq는 서로 다른 qqq입니다.
a.c 에 선언된 qqq는 선언된 위치에서 a.c 의 끝까지만 효력이 있을 뿐입니다.
b.c 에 있는 것도 역시 마찬가지고요.

Heejoon Lee

sala123의 이미지

빠른답변 무지 감사합니다. :D

그렇다면 a.c 에 전역변수로 선언한것은 static속성이 있다는것인가요?
다른 파일에서 extern 으로 접근이 가능한걸로 봐서는그렇지는 않은것같은데요...

결론적으로 만일 한개의 파일에서 전역변수를 선언하면 기본적으로는 static속성을 갖지만... 다른파일에서 extern하였다면
다른파일에서 extern한 변수에 대해서만 static속성이 해제된다고
생각해도 무리가 없을까요?

wafe의 이미지

"기본적으로 static 속성을 갖는다"라고 하기에는 좀 무리가 있는 것 같고요.
원래 전역변수의 유효 범위가 그 전역 변수를 선언한 곳 부터 그 파일의 끝까지인데요.
extern을 써서 다른 파일에 선언된 전역 변수의 범위를 그 파일까지 확장시켜 주는 거고요.
static을 붙여서 전역변수를 선언하면 아예 다른 파일로는 못 넘어가게 못을 밖아버리는 거지요.

어차피 의미는 비슷한 듯도 합니다만... ^^;;

Heejoon Lee

akbar의 이미지

sala123 wrote:

결론적으로 만일 한개의 파일에서 전역변수를 선언하면 기본적으로는 static속성을 갖지만... 다른파일에서 extern하였다면
다른파일에서 extern한 변수에 대해서만 static속성이 해제된다고
생각해도 무리가 없을까요?

C 에서는 그렇게 생각해도 무리는 없을 것 같습니다.
그러나 C++ 에서는 먹히지 않고 당연히 컴파일이 "안됩니다."
pynoos의 이미지

sala123 wrote:
그렇다면 a.c 에 전역변수로 선언한것은 static속성이 있다는것인가요?
다른 파일에서 extern 으로 접근이 가능한걸로 봐서는그렇지는 않은것같은데요...

결론적으로 만일 한개의 파일에서 전역변수를 선언하면 기본적으로는 static속성을 갖지만... 다른파일에서 extern하였다면
다른파일에서 extern한 변수에 대해서만 static속성이 해제된다고
생각해도 무리가 없을까요?

무리가 있습니다. static 이 없이 선언된 전역변수들은 모두 extern 이라고 생각해야합니다. 정확히 분류를 하자면, BSS에 생성되느냐 DATA에 생성되느냐의 차이라고 봐야하는데, 즉 초기값이 없느냐(BSS) 초기값이 있느냐(DATA)에 따라서, BSS에 들어가는 것들은 Common symbol로 간주되어 여러곳에 선언되어도 링커에 의해 하나만 남습니다. 하지만, DATA에 들어가는 초기값 있는 변수는 소스들이 하나의 binary를 만든다면 duplication 에러가 발생합니다.

위의 예에서 초기값을 주고 다시 시도해보세요.

그리고 참조할 만한 것은

nm a.o b.o

해보시고,

info nm

출력을 이해해 보세요.

rapzzard의 이미지

sala123 wrote:

그렇다면 a.c 에 전역변수로 선언한것은 static속성이 있다는것인가요?
다른 파일에서 extern 으로 접근이 가능한걸로 봐서는그렇지는 않은것같은데요...

이것은 기억수명과 통용범위에 대한 오해때문에 일어나는 것이 아닐까 싶습니다..
일반적으로 블럭밖에서 선언된 대상체들은 파일 통용범위(선언된 위치부터 파일의 끝까지)를 가지게 됩니다..
그것과 static이라는 기억수명과는 상관이 없습니다..(뭐 물론 linkage관점에서 얘기하는 static이 아닙니다)
예를 들어 블록통용범위에서 static으로 선언된 대상체가 있다고 가정할때 블록밖에서는 해당 변수를 가르킬 방법이 없지만(물론 포인터를 이용하면 가능합니다만) 해당 대상체자체가 기억장소에서 사라지는 것은 아닙니다..
그리고 기본적으로 파일통용 범위에서 선언된 대상체의 명칭은 기본적으로 외부연결을 가지게 됩니다..
akbar의 이미지

pynoos wrote:
sala123 wrote:
그렇다면 a.c 에 전역변수로 선언한것은 static속성이 있다는것인가요?
다른 파일에서 extern 으로 접근이 가능한걸로 봐서는그렇지는 않은것같은데요...

결론적으로 만일 한개의 파일에서 전역변수를 선언하면 기본적으로는 static속성을 갖지만... 다른파일에서 extern하였다면
다른파일에서 extern한 변수에 대해서만 static속성이 해제된다고
생각해도 무리가 없을까요?

무리가 있습니다. static 이 없이 선언된 전역변수들은 모두 extern 이라고 생각해야합니다. 정확히 분류를 하자면, BSS에 생성되느냐 DATA에 생성되느냐의 차이라고 봐야하는데, 즉 초기값이 없느냐(BSS) 초기값이 있느냐(DATA)에 따라서, BSS에 들어가는 것들은 Common symbol로 간주되어 여러곳에 선언되어도 링커에 의해 하나만 남습니다. 하지만, DATA에 들어가는 초기값 있는 변수는 소스들이 하나의 binary를 만든다면 duplication 에러가 발생합니다.

static 이 없이 선언된 전역변수들은 모두 extern 이라고 생각해야 하는 경우는 어디까지나 C 언어의 이야기입니다.
C++ 에서는 static 이 없이 선언된 전역변수는
extern 가 없다면 절대 extern 이 아닙니다.
만약 두 개의 파일 A.cpp 와 B.cpp 에서
int MyVar 라는 전역변수가 있을 경우
MyVar 의 초기화 여부에 상관없이 전역변수가 두 번 정의되었다는 에러가 나고 컴파일이 되지 않습니다.
즉 static 이 없이 선언된 전역변수들은 모두 DATA, BSS 영역에 잡히지만
Symbol 이 같을 수는 없습니다.(C++ 에서)

pynoos의 이미지

음.. 제가 뭔가를 잘못 쓴거 같군요.
제가 extern이라고 썼을때의 의미는

명시적으로 extern 이라는 키워드를 의미한 것이 아니라.

Quote:
그리고 기본적으로 파일통용 범위에서 선언된 대상체의 명칭은 기본적으로 외부연결을 가지게 됩니다..

에서의 외부연결이라는 의미였습니다.

즉 C에서 static을 쓰지 않았을 경우 extern 이라고 생각해야합니다 라고한 말을 정정합니다. 외부 모듈에서 link 가능한 것이라는 뜻으로요.

C에서 모든 것을 extern 이라고 생각한다면, 어디 정의되는 곳도 없을 것 아닙니까. 즉 외부 모듈에서 링크 가능하되 symbol duplication이 일어나야하는데, 그것은 linker가 제거해준다는 뜻이었습니다.

그런 암시적인 linker의 행위를 인정하며 프로그램하지 말아야 한다고 생각합니다.

a287848의 이미지

Quote:

예를 들어 블록통용범위에서 static으로 선언된 대상체가 있다고 가정할때 블록밖에서는 해당 변수를 가르킬 방법이 없지만

brace 밖에서 해당 변수를 가르킬수 있게 하기 위해서 brace 안에서 static 을 사용하는것 아닌가요?

같은 이름의 변수가 brace 밖에서 선언 되어있다면 duplication error 이 날것 같은데 정확하게 어떤 말씀인지?

제가 이해를 못하는 분위기 입니다. :roll:

Dig it.

eungkyu의 이미지

a287848 wrote:
Quote:

예를 들어 블록통용범위에서 static으로 선언된 대상체가 있다고 가정할때 블록밖에서는 해당 변수를 가르킬 방법이 없지만

brace 밖에서 해당 변수를 가르킬수 있게 하기 위해서 brace 안에서 static 을 사용하는것 아닌가요?


아닙니다. brace 안에서 static을 사용하면, 그 변수가 사용하는 메모리가 프로그램 수행 내내 유지된다는 것을 의미하는 것이지 밖에서 사용할 수 있게 하는 것이 아닙니다.
Quote:
같은 이름의 변수가 brace 밖에서 선언 되어있다면 duplication error 이 날것 같은데 정확하게 어떤 말씀인지?

이것 또한 아닙니다. :(

변수의 scope와 storage class를 헷갈리시는 듯 한데, 그 부분을 좀 더 보시면 좋을 것 같습니다.

댓글 달기

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