[C언어 오류] 에러코드 C2371:: (함수명):재정의. 기본 형식이 다릅니다.

두비니

·

2020. 4. 2. 23:44

 

 

 

 

 

 

 

자료구조 게시판의 선택정렬을 코딩하다가 생긴 일입니다.

 

 

 

 

 

**참고로 선택정렬 코드 자체가 엉망입니다. 선택정렬 자체가 궁금하신분들은 이 코드말고 아래 링크를 참조해주세요**

 

https://dokhakdubini.tistory.com/172

 

[자료구조] 선택정렬(Selection Sort)에 대하여

Data_Structure 선택정렬에 대하여 About. Selection Sort 정의: 1개이상의 서로 다른 정수를 가장 작은순서부터 배열하는 정렬 배열할때 가장 작은 수부터 배열하고싶으면, 가장 작은 숫자를 찾아서 맨 처음, 그..

dokhakdubini.tistory.com

 

 

 

#include <stdio.h>
#define swap(a, b, tmp){(tmp) = (a); (a) = (b); (b) = (tmp);}

int main() {
	int n, *list;

	selec_sort(*list, n);
}

void selec_sort(int *list, int n) {
	int i, j, tmp;
	int min = 1;

	for (i = 0; i < n; i++) {
		if (min > list[i]) {
			swap(min, list[i], tmp);
		}
	}

	printf("정렬된 배열: ");
	for (i = 0; i < n; i++) {
		printf("%d ", list[i]);
	}
}

빠른 이해를 위해 일부 코드만.

 

 

 

 

위 상황을 컴파일시키면 다음 오류때문에 컴파일이 불가능합니다.

 

이전에는 'identifier':재정의.기본 형식이 다릅니다.같은 경우만 봐왔는데

똑같은 변수를 두가지 변수형으로 선언한 경우와 비슷하지만, 이는 컴파일러의 특성을 알아보아야합니다.

 

 

 

 

기본적으로 컴파일러들은 소스를 한번 읽고 한번 번역하는 1PASS방식을 이용하기 때문에 컴파일러가 소스를 기계어로 번역할 당시 함수 호출코드는 있는데 그 함수를 본 적이 없다면  에러를 일으킵니다.

 

이는 C언어와같이 절차지향 언어들은 코드를 위에서부터 아래로 읽어내려가는

순차적인 처리가 매우 중요하게 여겨집니다.

 

따라서 위 코드의 경우, selec_sort()라는 함수를 보고 코드를 살펴보니, 처음 보는 함수여서

'이게 뭐야?'

라고 물어본 셈이죠.

 

 

 

그러면 왜 '재정의' 에러가 떴을까요?

 

 

 

그건 바로 컴파일러가 자료형이 적혀있지 않은 경우 int형으로 처리해주는 기능 때문입니다.

즉, 컴파일러가 함수호출상황을 보고 대충 눈치껏 함수의 반환형을 맞춰주는 것이지요.

이때 C언어의 기본 자료형은 int이기때문에 모든 함수의 반환형을 int라고 간주하고 컴파일링을 진행하게 됩니다.

 

 

결론적으로 컴파일러는 이경우에는 selec_sort()라는 함수를

int selec_sort() 인줄 알고있었던거고,

막상 컴파일을 해보니 void형인 selec_sort()함수를 보고,

 

'뭐야, 너 리턴형 다르게 재정의해버렸어'

 

라고 에러를 내뱉게 되는거죠.

 

 

 

 

컴파일러창을보면 이러한 경고가 있었던것도 알 수 있습니다.

extern은 그냥 '외부함수'정도로만 알아두면 됩니다.

 

 

 


 

!해결책

 

 

 

그러면 이 에러에 대한 해결책은 단순하게 코드의 위쪽에 미리 선언을 해주거나

아예 main함수의 위쪽에 함수를 작성해주면 되겠죠.

 

 

#include <stdio.h>
#define swap(a, b, tmp){(tmp) = (a); (a) = (b); (b) = (tmp);}

void selec_sort(int *list, int n);

int main() {
	int n, *list;

	selec_sort(*list, n);
}

void selec_sort(int *list, int n) {
	int i, j, tmp;
	int min = 1;

	for (i = 0; i < n; i++) {
		if (min > list[i]) {
			swap(min, list[i], tmp);
		}
	}

	printf("정렬된 배열: ");
	for (i = 0; i < n; i++) {
		printf("%d ", list[i]);
	}
}

 

 

 

::그래서 결론::

 

1. 원칙적으로 컴파일러는 처음보는함수를 만나면 컴파일러 에러를 발생시킨다.

2. 그러나 컴파일러들은 처음보는(extern) 함수들을 만나면 자동으로 int형으로 변환시켜준다. 

3. 외부함수를 이용할때는 번거로워도 꼭 미리 선언을 해주자.