헤더파일 전역변수 중복 오류

File:Program memory layout.pdf


재미난 일이 있었다

gcc에서는 문제 없는 코드가

visual studio 에서는 컴파일이 안되는 현상이 있었다


결론 요약

1. gcc랑 visual studio랑 헤더 파일 취급이 다름

2. 변수, 함수의 선언은 중복가능, 정의와 동시에 선언은 불가

3. header 파일은 extern 변수 선언, c 파일에는 변수 선언 및 정의



#1. gcc랑 visual studio랑 헤더 파일 취급이 다름 

type.h, main.c, func.c

*** type.h

#ifndef _type_h_

#define _type_h_

#include <stdio.h>


void show_var(void);

#endif



*** main.c

#include "type.h"

int var = 7;


int main()

{

show_var();

return 0;

}



*** func.c

#include "type.h"

extern int var;


void show_var(void)

{

printf("%d\n", var);

}




별거 아니다 그런데 위의 내용이 gcc에서는 오류 없이 컴파일 되었으나

visual studio에서는 func.c가 int var를 못 찾겠다고 오류를 뱉고 컴파일에 실패했다

중략하고 결론만 이야기 하면 type.h에 extern int var를 써줘야 하는게 원래 맞다고 한다


그런데 참 신기한 일이 main.c의 int var = 7를 type.h로 이동 시켰을 때다

visual studio는 그냥 컴파일이 된다 그러나

gcc는 ld(linker) 단계에서 (.rodata + @) multiple definition 오류가 난다

이건 사실 gcc쪽이 맞는거 같다


왜냐고 생각해보니 헤더를 파일에 복사할 때 일단 main.c, func.c에 _type_h_가 정의 된적 없으니

void show_var(void);랑 int var = 7;를 붙일 것이다

그리고 마지막에 모든 파일을 하나로 합치는 단계에서 main.c에도 int var = 7;이 있고

func.c에도 int var = 7;이 있으니 중복이 되어 오류를 출력하는 것이리라


그런데 왜 .rodata + @ 오류일까? 

initialized data니까 .data + @가 맞지 않으려나 


기타



#2. 변수, 함수의 선언은 중복가능, 정의와 동시에 선언은 불가

테스트 해봤다

*** test.c

void a(int);

void a(int);


int c;

int c;


int main()

{

c = 4;

a(c);

return 0;

}


void a(int b)

{

b+=8;

}


gcc에서 오류 없이 컴파일 된다 -Wall 해도 고요하다

but 

int c = 6;

int c = 3; 

이러면 당연하게 안된다

이 이상해보이는 바보 코드가 위의 의문스러운 문제의 해답이 되리라 :)



Posted by 쵸코케키

블로그 이미지
chocokeki
쵸코케키

공지사항

Yesterday
Today
Total

달력

 « |  » 2024.3
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31

최근에 올라온 글

최근에 달린 댓글

글 보관함