extern 과 함수 아규먼트에 대한 도움요청

neohwang의 이미지

다음의 코드 좀 봐주세요.

aaa.c

#include <stdio.h>

//extern void abcd(float rankvalue[],char rankstr[][120],int ranksize, float curvalue,char *curstr);

int main(int argc, char *argv[])
{
	float percent=1.0;

	float rankvalue[5]={-1.0,};
	char rankstr[5][120]={{(char)NULL,},};
	char tmpstr[150];

	abcd(rankvalue,rankstr,5,percent,tmpstr);
	return 0;
}

bbb.c

#include <stdio.h>

void abcd(float rankvalue[],char rankstr[][120],int ranksize, float curvalue,char *curstr)
{
	printf("[%s]\n",curstr);
}

위의 두개의 파일을 다음과 같이 컴파일하고 실행하면

Quote:
[view@dream ver41]$ gcc -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.96/specs
gcc version 2.96 20000731 (HancomLinux 2.2 2.96-99hl)
[view@dream ver41]$ gcc -o aaa aaa.c bbb.c
[view@dream ver41]$ ./aaa
세그멘테이션 오류
[view@dream ver41]$

왜 오류가 떨어지나요?
위에서 extern 부분의 주석을 제거하면 정상적으로 수행이 됩니다.
또한 abcd()함수의 아규먼트의 수를 조금 변경하면 extern 부분을 주석처리해도 오류가 생기지 않습니다.

제가..뭔가 기본적인 사항을 놓친것 같은데..
또한 지금까지 extern을 굳이 않해도 컴파일에 문제가 없어서 생략을 많이 했는데..

많은 지도 부탁드립니다.

(p.s) 문제의 핵심은 함수 아규먼트에 대한 기본부족이 아닌가 하는 생각이 많이듭니다. 하지만 두개의 파일을 합쳐서 컴파일하면 오류가 생기지 않습니다.
또한 위의 함수 아규먼트중 "float curvalue" 같은 것을 빼면 어떤경우에도(extern을 하건 말건, 합치건 분리하건) 오류가 생기지 않습니다.

거참 모르겠습니다.

cinsk의 이미지

함수의 원형(prototype)을 제공하지 않고 쓰는 것은 매우 좋지 않은 습관입니다. 설령 컴파일 잘 되었다고 쓰지 않는 것도 매우 위험합니다.

가능한 함수 원형을 미리 제공하기 바랍니다.

segmentation fault가 나는 이유는, 짧게 말하면 다음과 같습니다:

일단 함수의 prototype이 없는 경우, 컴파일러는 함수에 전달되는 argument들을 변환합니다. int보다 작은 integer type (char 포함)은 모두 int로, 큰 것은 모두 long으로, float은 double로 등등.. 그리고 변경한 다음 그 함수에 전달하는 코드(기계어)를 만들어 냅니다. 그리고 실제 나중에 따로 컴파일된 함수의 코드는 float이나 char가 들어온다고 생각하지만, 이미 호출하는 부분은 double이나 int로 변경되어 전달한 코드로 만들어져 있는 상태이기 때문에, 얼마든지 segmentation fault가 날 수 있습니다.
(쩝, 말하고 나니 짧게 말한 건 아니군요)

컴파일러를 쓸 때 (gcc의 경우 -Wall) 경고를 최대한 알려달라는 옵션을 쓰고 컴파일하면, prototype이 없는 경우 경고를 보여 주기 때문에, 좋지 않는 습관을 미리 막을 수 있습니다. 그럼 이만.

neohwang의 이미지

긴 답변 감사합니다. ^^
좋은 하루 되세요.

댓글 달기

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