헤더에 변수 선언에 대해 여쭤볼 것이 있습니다.
글쓴이: hoochoona / 작성시간: 월, 2014/12/29 - 4:51오후
헤더가 중복포함 되지 않기 위해 방지하는 것이 include guard가 있지 않습니까?
헌데 여기서 의문점인것이 include guard가 적용된 헤더안에서 변수를 선언 하게되면 에러가 발생하는데, ODR에 어긋나게 되어 에러가 발생하게 되는것 같습니다.
더 자세하게 이야기를 풀어보면...
//test.h #ifndef _TEST_H_ #define _TEST_H_ int g_i = 0; #endif // _TEST_H_
위와 같은 test.h 라는 헤더파일이 존재 합니다. #ifndef ~ #endif 사이는 한번 읽히게 되면 _TEST_H_ 가 정의되기에 그 다음 부터는 읽혀지면 아니되는것으로 알고 있었습니다만...
이상하게도 g_i 는 ODR(One Definition Rule)에 어긋나게되어 에러가 발생되는 것 같습니다. 어차피 한번 읽힐테니 한번 선언 될텐데 말입니다.
그런데 여기서
//test.h #ifndef _TEST_H_ #define _TEST_H_ int g_i; #endif // _TEST_H_
g_i 에 값을 초기화 하지 않은 전역변수라면 문제없이 한번 선언이 되어 ODR에 어긋나지 않아 에러가 발생되지 않습니다.
왜 그런지 알 수 있을까요?
해답을 알고싶습니다.
Forums:
음 ..
storage class 가 명시되지 않으면 extern 이 생략된 것과 같이 취급되니..
앞에 extern 을 붙여 보면.. 두 번째 것이 전혀 문제가 없다는 건 금방 이해가 가실테고..
첫 번째 것은 external linkage 를 갖는 녀석을 초기화 하려하니, 중복 선언 에러가 나는 거죠..
앞에 static 을 붙여서 internal linkage 로 바꿔주면 문법상 전혀 문제가 없습니다.
다만, 원래의 의도가 external linkage 를 원한 것이라면..
두 번째 처럼 선언만 하고, 초기화는 프로그램 내에서 별도로 하셔야 합니다.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
질문 있습니다.
1. 저장소 지정자가 명시되지 않으면 기본으로 extern인가요?
함수는 기본적으로 extern으로 된다는 건 알고 있었습니다만 모든 선언에 대해 맞는지 궁금합니다.
아니면 변수와 함수 간에 기본 저장소 지정자가 다르게 정의되어있는지?
저는 이렇게 생각했습니다.
음 ..
> storage class 가 명시되지 않으면 extern 이 생략된 것과 같이 취급되니..
> 앞에 extern 을 붙여 보면.. 두 번째 것이 전혀 문제가 없다는 건 금방 이해가 가실테고..
아뇨.. global variable 은 default 가 extern 도 아니고 static 도 아니라서..
extern 을 명시적으로 붙인 것과는 다른데.. 제가 착각하고 설명을 전혀 엉뚱하게 했습니다.
보통은 실제 모듈 안에 심볼을 정의하고, 헤더에 extern 을 넣는다는 얘기를 한다는게.. 뭔가 빼먹고 이상한 결론만 넣었네요.
이해하고 계신게 맞고, 추가로 아래 jick 님이 올리신 링크 참조하시면 더 도움이 될겁니다.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
일하다가, 갑자기 정말 문뜩 떠올랐던
일하다가, 갑자기 정말 문뜩 떠올랐던 생각이였습니다.
include guard 가 적용 되어있는 헤더가 변수 중복 선언 에러가 발생하게 되는 원리가 뭘까 라는 생각이 번뜩였습니다.
찾아보고는 있지만 여전히 해답을 알 수가 없어서 살짝 묘하네요...
헤더안에서 앞에 키워드가 안붙은 변수선언은 하지 않는 편입니다만.
질문글에서 말씀드렸던것과 같이 include guard가 적용되어있음에도 불구하고 변수 선언 라인을 두번 이상을 읽는 다는 점이 여전히 모르겠군요~
내부적으로 #ifndef ~ #endif 조건이 맞지 않아도 컴파일러가 읽는 것도 아니지 말입니다.
-----------------------------
안녕하세요. 후추나입니다.
http://blog.naver.com/chhh92
...
실패는 좋은 경험치.
찾아보니 Common symbol이라고 하는군요
여기의 첫번째 답변에 설명이 잘 되어 있는 것 같습니다.
http://stackoverflow.com/questions/3691835/why-uninitialized-global-variable-is-weak-symbol
정보 감사합니다. :)
정보 감사합니다. :)
-----------------------------
안녕하세요. 후추나입니다.
http://blog.naver.com/chhh92
...
실패는 좋은 경험치.
댓글 달기