extern 은 옵션이다???
글쓴이: freezm7 / 작성시간: 금, 2004/08/27 - 2:40오후
== main.c int share; void share20(); int main(int arg, char** argv) { share = 10; printf("%d\n", share); share20(); printf("%d\n" share); } == sub.c int share; void share20() { share = 20; } ==
gcc main.c sub.c
하면 상식(제가 알고 있는한)
링크 에러가 떠야 할 것 같습니다.
main.o 에도 share 라는 변수가 있고
sub.o 에도 share 라는 변수가 있으니까요.
그런데 아무 문제없이 컴파일이 됩니다.
그리고 결과는
10
20
으로 출력되네요.
어떻게 이런일이???
Forums:
[code:1]int share; ====> extern int s
int share; ====> extern int share = 0;
전역 변수의 기본값이 위와 같기 때문입니다. 그래서 extern 따로 붙이 필요 없이 잘 되죠.이 내용은 책 함 보면은 나올긴데...-_-ㅋ
<어떠한 역경에도 굴하지 않는 '하양 지훈'>
#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);
int sharedouble share 여도.. 컴파일되고 실행도
int share
double share 여도.. 컴파일되고 실행도 될걸요..
...
다만.. 결과가.. 미묘해지겠지만 =3=33
정도로 컴파일하고 실행시켜보시면...
..
이런 결과가 나옵니다..
...
외부에서 쓸 일 없는 전역변수라면.. static을.. 붙여줘서 이런 일이
발생하지 않도록 해야겠죠 :)
오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...
http://mytears.org ~(~_~)~
나 한줄기 바람처럼..
[quote="서지훈"][code:1]int share; ====>
링크시 이름 충돌이 왜 안 일어나는지에 관한 질문인데, 기본값이 위와 같다는게 무슨 관련이 있는지 모르겠네요.
태영님, 예제까지 만들어 실험해 주셔서 감사합니다.
근데 제 질문은 결과가 궁금한게 아니라,
(저렇게 되는 결과를 보고 제가 질문한 것이죠 ^^;)
과정, 즉, 왜 이름 충돌 없이 링크가 되냐는 것입니다.
조금 더 알려주시면 감사하겠습니다.
즐겁게 살아 볼까나~*
원래가 extern이라는 키워드가 외부의 변수를 그대로 사용을 하겠다는
원래가 extern이라는 키워드가 외부의 변수를 그대로 사용을 하겠다는 의미입니다.
따로 새로 선언을 해줄 필요가 없이.
그렇기 때문에 main.c와 sub.c에서 선언된 int share; 이 변수는 같은 변수 입니다.
초기화선언은 main.c에서 선언 한데로 사용이 되고, sub.c에서 main.c에서 선언된 share 변수를 새로운 선언 없이 사용을 하는 거구요.
지금 변수가 선언이 된게 share 하나 밖에 없으니 충돌이 날려도 날 수가 없죠.
손바닥도 마주쳐야 소리가 나듯...-_-ㅋ
아마도... extern의 의미에 혼동이 있으신듯 하네요^^
<어떠한 역경에도 굴하지 않는 '하양 지훈'>
#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);
혼동하시는 분은 서지훈님 같은데요.원 코드는 one definitio
혼동하시는 분은 서지훈님 같은데요.
원 코드는 one definition rule에 어긋나므로 분명히 잘못된 것입니다.
그리고 코드에 잘못이 있는 이상 그 결과는 undefined입니다.
왜 이런 결과가 나오는지 따지는 것은 무의미하죠.
[quote="doldori"]혼동하시는 분은 서지훈님 같은데요.원
http://bbs.kldp.org/viewtopic.php?t=28535&highlight=extern+static
기본적으로 static 을 붙이지 않으면.. extern 속성을 가지는 걸로 알고 있습니다..
그러나 결과가 undefined는 아닌것 같군요 흐흐흐
http://sal.hongik.ac.kr/~sikim/Courses/2004/sp/lecture/files/linker&loader.ppt
9~11 페이지쯤에서.. weak symbol , strong symbol 등 얘기 등과 관련된 것들을 읽어보시면.. freezm7 님이 원하시는 답은 찾을 수 있으실거 같군요 :)
int share = 1;
식으로 둘 다 strong symbol 이 된다면.. 링크할때 에러가 나겠지만..
아니면.. 위의 자료에 있는 내용에 따라서 :) 링크가 되겠죠..
외부에서 쓸 일 없는 변수들엔 static을 붙이는 습관을 들이세요 흐흐
오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...
http://mytears.org ~(~_~)~
나 한줄기 바람처럼..
[quote="정태영"]그러나 결과가 undefined는 아닌것 같군요
말씀하신 weak symbol, strong symbol 등은 C 언어에서는 정의되지 않은
개념입니다. hclc에서 이와 비슷한 논의가 있었습니다.
http://groups.google.co.kr/groups?selm=bd0fn2%2412c%241%40news.hananet.net
무의미한 짓..
무의미한 짓 한번 해봤습니다.
일단 덤프는
코드는 아래와 같습니다.
참고로 VC++ 6.0에서 컴파일 했습니다.
힙을쓰는 전역이 정의에 따라 double로 읽을때는 double로 읽히고 int로 읽을때는 int로읽히며, 쓰기에서도 마찬가지이며, 이는 포인트 캐스팅을 통해 값을 접근했을때
이같은 결과로 나오는걸로 볼때 같은 주소에 캐스팅에 의한 값의 접근 결과로 이상한 값이 나온것으로 추측하였고 이를 뒷받침하기 위해 삽질좀 더해봤습니다... :shock:아래와 같이 소스 수정하여 더블형이 표나도록 값을 입력시켜 줘보았습니다.
맨티사 부분이라 무지 큰수를 집어넣어야 영향을 줄 수 있었습니다.
된장:cry: 0.000001변하는군요..
머나먼 땅으로 우리 동무가 이제 떠나간다네.
고향의 바람이 불어와 동무 뒤를 따르고
사랑스러운 도시가 푸른 이내 속에서 사라지네.
정든 집, 푸른 동산, 부드러운 눈길도...
Re: extern 은 옵션이다???
doldori 님이 링크하신 뉴스 그룹의 토론 내용을 정리합니다.
http://groups.google.co.kr/groups?selm=bd0fn2%2412c%241%40news.hananet.net
main.c에서 파일 통용범위의 대상체 share는 extern이라는 기억부류 지정자나 초기치가 없기 때문에 완전한 정의가 아닌 tentative definition으로 다루어 집니다. tentative definition은 해당 명칭에 대한 분명한 정의가 없을 경우 translation unit의 마지막, 즉 프로그램의 소스 끝에서 0을 초기치로 갖는 정의로 다루어 집니다.
sub.c에서 역시 마찬가지입니다.
이렇게 보면 두개의 프로그램 소스에 임시정의 int share;가 두번 정의된 것이라고 볼 수 있습니다. 위에서 몇 분이 말씀해 주셨듯이 파일 통용범위에서 선언된 대상체는 외부 연결을 갖는 명칭이기 때문에 프로그램 전체에서 두번 선언된 셈입니다. 본래 C의 외부 정의 모델에 따르면 이러한 프로그램은 잘못된 것입니다.
그러나 유닉스 계열의 임플리멘테이션에서 사용하는 완화된 참조/정의 모델에서는 이와 같은 정의되지 않는 행동을 확장으로 지원하여 쓰이고 있습니다.
(IT 백두대간 C 언어, 전웅, p.914 여기서 잠깐)
大逆戰
넘 얘기가 또 어려워 지는군요.넘 어려워서 이해하기 힘들고.간단히
넘 얘기가 또 어려워 지는군요.
넘 어려워서 이해하기 힘들고.
간단히... 원론적인거...
제가 아는 전역 변수는 기본적으로 extern으로 선언이 되고, 0으로 셋팅이 되는 걸로 아는데?
이게 undefined라는 건지?
아님 tentative(시험적인 - 방금 사전에서 뜻 확인)인지?
지금 얘기는 흘러 흘러 가고 있는데...
여러 의견은 나오고 있는데...
얘기의 정확한 근거와 하고자 하는 얘기의 논지는 끝부분에 명확히 하면은 또 좋은 자료가 될듯하네요.
만약 제가 알고 있는게 틀렸다면, 또 기쁘게 한가지를 더 배우게 되는 일^^
<어떠한 역경에도 굴하지 않는 '하양 지훈'>
#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);
정의(definition)와 선언(declaration)의 의미를 정확히
정의(definition)와 선언(declaration)의 의미를 정확히 알아야 합니다.
정의는 "이러한 함수 또는 개체를 만들라",
선언은 "이러한 함수 또는 개체가 어딘가에 있으니 참고하라"고
컴파일러에게 알려주는 것입니다.
그리고 선언은 여러 번 해도 되지만 정의는 단 한 번만 할 수 있습니다.
원 코드에서 share는 두 번 정의했으므로 이 규칙을 위반한 것이며,
이 경우 implementation은 마음대로 할 수 있습니다. 링크 에러를 낼 수도
있고 아무 문제가 없는 것처럼 보일 수도 있습니다.
원 코드를 맞게 고치면
// main.c
extern int share; // 선언. 보통 이 문장은 헤더에 넣어 #include 함
...
// sub.c
int share; // 정의
...
정도가 되겠죠.
[quote="doldori"]정의(definition)와 선언(decl
이게 맞는 표현 같은데요...-_-ㅋ
<어떠한 역경에도 굴하지 않는 '하양 지훈'>
#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);
[quote="서지훈"][quote="doldori"]정의(definit
doldori님이 맞습니다.
TCPL같은 책 해당부분 찾아서 읽어보심이 좋을듯 합니다.
Re: extern 은 옵션이다???
(다시한번 말씀드리지만) 그렇게 원칙을 위반한 코드임에도 불구하고 유닉스 환경의 임플리멘테이션에서는 이것을 확장으로 인정해 왔다는 것입니다. 그래서 OP는 아무 문제 없이 컴파일되었다는 점을 물어본 거구요.
'TCPL' 이게 무슨 책인지 잘 모릅니다만 (K&R2인가요? The C Programming Language?? 맞는거 같은데) 한빛미디어에서 출판된 전웅님이 쓰신 'IT 백두대간 C 언어 펀더멘탈'을 이용해서 공부하시길 권하는 바입니다.
'13장 외부 정의 모델'에 해당 내용이 자세히 설명되어 있습니다.
大逆戰
Re: extern 은 옵션이다???
논외입니다만, 전웅님책이 현재 품절 상태이고,
출판사에서 더 찍을지 말지 고민하고 있는 상태라고 합니다.
관심있으신 분들 한번씩 전화날려주시기 바랍니다.
The C Programming Language 를 무슨 책인지 잘 모른다고 하시며
변두리 책 취급하시면 많은 분들이 섭해하지 않으실까요? 8)
Re: extern 은 옵션이다???
오해이십니다.
K&R2를 white book이라고 부르는 경우는 자주 봤지만 TCPL이라고 들어본 적이 없기 때문에 그런 말을 남긴겁니다.
大逆戰
댓글 달기