이 문서는 GCC Version 2.7.2를 기준으로 하여 이 컴파일러가 출력하는 에러 [error]와 경고 [warning] 메시지를 한국어로 번역하고, 그 메시지를 발생할 수 있는 간단한 예제를 보이며, 간단한 해결책을 제시합니다.

 

GCC Error (Warning) Message List

Copyright © 1999 Seong-Kook Cin

   Seong-Kook Cin Jang-Chon Dong 21-2 Sun-Chon City 540-190 South KOREA

   

Before reading this

이 문서는 GCC Version 2.7.2를 기준으로 하여 이 컴파일러가 출력하는 에러 [error]와 경고 [warning] 메시지를 한국어로 번역하고, 그 메시지를 발생할 수 있는 간단한 예제를 보이며, 간단한 해결책을 제시합니다.

이 문서는 C 배우미들이 낯선 컴파일러 메시지를 만났을 때 당황하지 않고 쉽게 문제를 해결할 수 있기를 바라는 뜻에서 만들어진 것입니다.

이 문서는 유용하게 쓰여지기를 바라면서 만들어졌지만 저자는 이 문서에 대해 어떠한 보증도 하지 않습니다. 즉, 이 문서에 의해 일어날 수 있는 손해에 대해서는 책임을 지지 않습니다.

이 문서는 GCC가 발생할 수 있는 에러 메시지를 모두 포함하지 않을 수도 있습니다. 여러분이 이 문서에 없는 에러 메시지를 발견해서, 이 문서에 추가하기를 원하거나, 이 문서에 틀린 곳을 수정하기를 원한다면

cinsk@acm.org 으로 e-mail을 보내시기 바랍니다. 어떠한 제안이나 비판도 환영합니다. 저자는 여러분들의 참여로 이 문서가 보다 완전해지기를 원합니다.

   

Conventions

영어를 한국어로 쓸 때, 한국어를 영어로 표기할 때 혼동을 가져올 수 있는 용어나 기타 부가적인 설명은 그 용어 뒤의 `[]'안에 옵니다. 문서의 형식은 다음과 같습니다.

에러 메시지

에러 메시지 설명......................

이 에러 메시지를 발생시키는 예제

   

파일:줄 번호: 실제 컴파일러가 발생하는 에러 메시지

   

Table of Contents

Errors

   

   

   

   

   

   

   

   

Warnings

   

   

   

   

   

   

   

warning: initializer-string for array of chars is too long

주어진 배열이 가질 수 있는 문자의 개수보다 많은 초기값이 주어진 경우에 발생합니다. C 언어의 문자열은 큰 따옴표(`"')로 둘러싸서 나타내며 문자열의 끝을 나타내기 위해 ASCII 코드 0번 문자(`\0')를 사용합니다. 따라서 아래의 예에서 배열 `ca'는 크기가 5로 되어 있어야 합니다.

문자열 배열을 쓸 때마다 이런 식으로 배열의 크기를 지정해 주는 것은 번거로운 일입니다. 배열이 초기값을 가지고 있을 때에는 배열의 크기를 지정하지 않아도(`ca[]') 좋습니다.

char ca[3] = "abcd";

   

file:1: warning: initializer-string for array of chars is too long

   

invalid #-line

라인 [line] 번호 정보를 잘못 입력한 경우에 발생합니다. 라인 번호는 0보다 큰 양수 [positive number]이어야 합니다.

invalid format `#line' directive 에러를 참고하시기 바랍니다.

# 0 "foo.c"

   

file:1: invalid #-line

또는,

#line 0

   

file:1: invalid #-line

   

parse error before `XXX'

이 에러가 발생하는 조건은 너무나도 많습니다. 일반적으로 문장을 분석 [parse]할 때 예상하지 못한 구문을 발견했을 경우에 이 에러가 발생합니다. parse error 에러를 참고하기 바랍니다.

조건 1: typedef로 정의한 형에 short, long, signed, unsigned 등을 사용할 때.

typedef int INT;

unsigned INT ui;

   

file:2: parse error before `ui'

file:2: warning: data definition has no type or storage class

조건 2:

void f()

{

else {

}

}

   

file: In function `f':

file:3: parse error before `else'

   

warning: `XXX' redefined

사용자가 정의한 매크로를 다시 정의하거나, ANSI C 혹은 컴파일러가 미리 정의해 놓은 매크로를 재 정의하려 할 때 발생합니다. 사용자가 정의한 매크로인 경우, #undef 지시어를 써서 이 경고를 없앨 수 있습니다.

#define MY_CONST "cinsk"

#define MY_CONST "windy"

   

file:2: warning: `MY_CONST' redefined

   

warning: undefining `XXX'

ANSI C 혹은 컴파일러가 미리 정의해 놓은 매크로(predefined macro)를 없앨 경우에 발생합니다. 이 경고가 발생할 경우, 여러분은 다른 매크로를 써야 합니다. 미리 정의된 매크로를 다른 목적으로 쓰는 것은 좋지 않습니다. ANSI C 혹은 컴파일러가 미리 정의해 놓은 상수 목록은 컴파일러와 함께 제공되는 매뉴얼을 참고하시기 바랍니다.

#undef __FILE__

   

file1: warning: undefining `__FILE__'

   

ANSI C requires a named argument before `...'

ANSI C는 하나 이상의 가변 인자 [variable length argument]를 받을 수 있게 하지만 하나 이상의 고정된 인자가 있어야 합니다. 아래의 예에서 함수 f()는 고정된 인자가 하나도 없기 때문에 이 에러가 발생합니다.

void f(...) { }

   

file:1: ANSI C requires a named argument before `...'

   

unterminated macro call

주어진 매크로의 인자를 읽을 때 괄호가 닫히지 않을 경우 이 에러가 발생합니다.

#define NOP(x)

NOP(foo

   

file:2: unterminated macro call

   

duplicate argument name `XXX' in `#define'

매크로를 정의할 때 같은 이름을 두 인자에 대해 썼을 경우 이 에러가 발생합니다.

#define ADD3(a, a, c) ((a) + (b) + (c))

   

file:1: duplicate argument name `a' in `#define'

   

parse error

어구 분석(parsing)에 실패했을 경우 이 에러가 발생합니다. 이 에러가 발생하는 경우는 매우 많습니다. parse error before `XXX' 에러를 참고하기 바랍니다.

조건 1: `#elif' 다음에 상수식이 오지 않을 때

#if defined(ONE)

int i = 1;

#elif

int i = 2;

#endif

   

file3: parse error

조건 2: 비어있는 매크로를 잘못 썼을 때.

#define EMPTY

#if EMPTY

char *msg = "EMPTY is non-empty";

#endif

   

file:2: parse error

   

empty character constant

빈 문자 상수가 쓰였을 때 이 에러가 발생합니다.

int i = '';

   

file:1: empty character constant

   

empty file name in `#include'

`#include' directive에서 파일 이름이 주어지지 않았을 때 발생합니다.

#include <>

   

file:1: empty file name in `#include'

   

unbalanced `#endif'

`#endif' directive가 if 섹션 ('#if', `#ifdef', `#ifndef' 등으로 시작하는) 과 맞게 쓰이지 않을 때 발생합니다.

#endif

   

file:1: unbalanced `#endif'

   

warning: declaration of `xxx' shadows a parameter

int f(int i)

{

enum e { l, j, k, i};

}

   

file: In function `f':

file:3: warning: declaration of `i' shadows a parameter

file:4: warning: control reaches end of non-void function

   

warning: integer overflow in expression

정수로 취급되는 식 (enumerator 포함)에서 오버플로우(overflow)가 일어날 경우에 이 경고가 발생합니다.

#include

   

enum A { AA = INT_MAX + 1 };

   

file:3: warning: integer overflow in expression

   

#error XXX

이 에러는 컴파일러에게 소스가 전달되기 전, 프리프로세서(preprocessor)에 의해 발생합니다. 프리프로세서는 `#error'로 시작하는 문장을 만나면 바로 컴파일 작업을 중단하고 `#error' 문장을 출력합니다. 이는 대개 프로그램 소스가 특별한 환경을 요구하는 경우, 적합하지 않은 환경일 때에는 컴파일이 되지 않게 하기 위한 목적으로 쓰입니다.

ANSI C에서는 몇 개의 미리 정의된(predefined) 상수를 정의하고 있고, 컴파일러에 따라서 추가적인 상수를 제공합니다. `#error'의 경우, 이들 상수와 같이 쓰이는 경우가 일반적이므로, 자세한 것은 컴파일러의 매뉴얼을 참고하시기 바랍니다.

#ifndef NEVER_DEFINED

#error NEVER_DEFINED required

#endif

file:2: #error NEVER_DEFINED required

   

parameter name omitted

int f(int)

{

return 0;

}

   

file:1: parameter name omitted

   

`XXX' declared as function returning an array

int f(void)[];

   

file:1: `f' declared as function returning an array

   

called object is not a function

void f(void)

{

char *p;

p();

}

   

file: In function `f':

file:4: called object is not a function

   

   

warning: `return' with no value, in function returning non-void

int f(void)

{

return;

}

   

file: In function `f':

file:3: warning: `return' with no value, in function returning non-void

   

file

   

unterminated character constant

문자 상수가 `''로 닫히지 않을 경우에 발생합니다.

char ch = 'a;

   

file:1: unterminated character constant

   

unterminated comment

주석 [comment]이 `/*'로 닫히지 않을 경우에 발생합니다.

/* This is a comment

   

file:1: unterminated comment

   

unterminated string or character constant

문자 상수나 문자열이 `"'로 끝나지 않을 경우에 발생합니다.

char *str = "cinsk\

the wind

   

file:1: unterminated string or character constant

file:2: possible real start of unterminated constant

   

possible real start of unterminated constant

문자 상수나 문자열이 `"'로 끝나지 않을 경우에 발생합니다.

char *str = "hello\

world

   

file:1: unterminated string or character constant

file:2: possible real start of unterminated constant

   

warning: return-type defaults to `int'

함수의 리턴 형 [return type]을 생략할 경우에 발생합니다. 리턴 형이 생략된 함수의 리턴 형은 `int'입니다.

foo(void)

{

return 0;

}

   

file:2: warning: return-type defaults to `int'

   

warning: control reaches end of non-void function

함수의 리턴 형 [return type]이 `void'가 아닌데도 함수가 `return' 문을 가지지 않을 경우에 발생합니다. 이 경우 함수를 `void' 형으로 선언하거나 `return' 문을 쓰면 해결됩니다.

int foo(void) {}

   

file:1: warning: control reaches end of non-void function

   

warning: dereferencing `void *' pointer

void 형 포인터 [pointer]는 다른 형 포인터로 캐스트 [cast]하기 전에는 쓸 수 없습니다. 즉, 이 에러는 void 형 포인터에 역참조 [dereference] 연산자인 `*'를 썼기 때문에 발생합니다. 이 에러를 해결하려면 void 형 포인터를 다른 형 포인터 (예를 들어 `int *')로 캐스팅 [casting]해서 쓰면 됩니다.

void foo(void)

{

void *p, *q;

*(p = q);

}

   

file:4: warning: dereferencing `void *' pointer

file:4: warning: value computed is not used

   

dereferencing pointer to incomplete type

정의되지 않은 형을 가리키는 포인터 [pointer]에 역참조 [dereference] 연산자(`*')를 쓸 수 없습니다.

struct s;

void g(struct s *);

void f(void)

{

struct s *p;

g(*p);

}

   

file:6: dereferencing pointer to incomplete type

   

warning: passing arg N of `XXX' makes integer from pointer without a cast

함수 XXX의 N번째 파라메터 [parameter]가 정수형인데도 캐스팅 [casting]없이 포인터를 인자 [argument]로 쓴 경우에 발생합니다.

void f(int);

void g(void)

{

f("erroneous");

}

   

file:4: warning: passing arg 1 of `f' makes integer from pointer without a cast

   

int f(char *);

void g()

{

f(5);

}

   

file: In function `g':

file:4: warning: passing arg 1 of `f' makes pointer from integer without a cast

   

   

incompatible type for argument N of `XXX'

함수 선언에 쓰인 파라메터 [parameter]의 형과 실제 인자 [argument]의 형이 서로 달라서 변경할 수 없는 경우에 발생합니다.

struct s { int a; } p;

void f(void)

{

void g(int, int);

g(5, p);

}

   

file:5: incompatible type for argument 2 of `g'

   

too few arguments to function `XXX'

함수 선언에 쓰인 파라메터 [parameter]의 수보다 실제 인자 [argument]의 개수가 적을 경우에 발생합니다.

void f(void)

{

void g(int, int);

g(5);

}

   

file:4: too few arguments to function `g'

   

too many arguments to function `XXX'

함수 선언에 쓰인 파라메터 [parameter]의 수보다 실제 인자 [argument]의 개수가 많을 경우에 발생합니다.

void f(void)

{

void g(int);

g(5, 2);

}

   

file:4: too many arguments to function `g'

   

incompatible types in assignment

대입 [assignment] 연산에서 연산자 `=' 사이의 오퍼랜드 [operand]의 형이 서로 완전히 다릅니다. assignment makes integer from pointer without a cast 경고를 참고하시기 바랍니다.

struct s {};

void f()

{

struct s st;

int i;

i = st;

}

   

file:7: incompatible types in assignment

   

warning: assignment makes integer from pointer without a cast

대입 [assignment] 연산에서 연산자 `=' 양쪽에 오는 오퍼랜드 [operand]가 왼쪽은 정수형, 오른쪽은 포인터일 경우에 이 경고가 발생합니다. 이를 해결하려면 포인터를 정수형으로 캐스팅 [casting]해야 합니다. incompatible types in assignment 에러를 참고하시기 바랍니다.

void f()

{

char *cp;

int i;

i = cp;

}

   

file:5: warning: assignment makes integer from pointer without a cast

   

top-level declaration of `XXX' specifies `auto'

함수 바깥에 선언된 선언에 `auto' 키워드가 쓰였습니다. `auto' 키워드는 자동 변수 [automatic variable]를 선언하기 위해 쓰는 것이므로 전역 변수 [global variable]에 쓰일 수 없습니다.

auto int i;

   

file:1: top-level declaration of `i' specifies `auto'

   

register name not specified for `XXX'

`register' 키워드는 자주 쓰이는 변수를 메모리 대신 (가능하다면 [if possible]) CPU의 레지스터 [register]를 쓰도록 합니다. 전역 변수 [global variable]에는 `register' 키워드를 쓸 수 없습니다.

register int i;

   

file:1: register name not specified for `i'

   

redeclaration of `XXX'

같은 스코프 [scope] 안에 같은 이름이 쓰인 경우에 발생합니다. 다른 변수 이름을 써야 할 것입니다. 이 에러는 `XXX' previously declared here 에러와 함께 발생합니다.

void foo()

{

int i;

int i;

i = 3;

}

   

file:4: redeclaration of `i'

file:3: `i' previously declared here

   

`XXX' previously declared here

같은 스코프 [scope] 안에 같은 이름이 쓰인 경우에 처음 선언한 곳을 나타내 줍니다. 이 에러는 redeclaration of `XXX' 에러와 함께 발생합니다.

void foo()

{

int i;

int i;

i = 3;

}

   

file:4: redeclaration of `i'

file:3: `i' previously declared here

   

`#include' expects "FILENAME" or <FILENAME>

`#include'에 쓰이는 파일 이름은 `"'나 `<>'로 둘러싸야 합니다.

#include stdio.h

   

file:1: `#include' expects "FILENAME" or <FILENAME>

   

numeric constant contains digits beyond the radix

주어진 수치 상수 [numeric constant]가 진법에 맞지 않을 경우에 발생합니다. 예를 들어 8 진수에서 쓰일 수 있는 숫자는 0, 1, ..., 7인데 아래의 예처럼 8을 쓴다거나, 16 진수에서 쓰일 수 있는 문자는 a, b, ..., f인데 f 이후의 문자를 쓸 경우에 발생합니다.

int i = 08;

int j = 0xah;

   

file:1: numeric constant contains digits beyond the radix

file:2: numeric constant contains digits beyond the radix

   

`#' operator is not followed by a macro argument name

`#' 매크로 연산자는 매크로 인자 [argument] 앞에 나와 이 이 인자를 문자열 [string]로 만들어주는 역할을 합니다. `#' 연산자가 매크로 이름 앞에 나오지 않은 경우에 이 에러가 발생합니다.

#define bug(s)        s #

   

file:1: `#' operator is not followed by a macro argument name

   

`##' at start of macro definition

`##' 매크로 연산자는 두 개의 인자 [argument]를 받아 이들을 하나의 토큰 [token]으로 바꾸어 줍니다. 따라서 `##' 연산자는 `+' 연산자처럼 쓰이며 양쪽에 인자가 와야 합니다. `##' 연산자 앞에 인자가 오지 않을 때 이 에러가 발생합니다.

#define bug(s)        ## s

   

file:1: `##' at start of macro definition

   

`##' at end of macro definition

`##' 매크로 연산자는 두 개의 인자 [argument]를 받아 이들을 하나의 토큰 [token]으로 바꾸어 줍니다. 따라서 `##' 연산자는 `+' 연산자처럼 쓰이며 양쪽에 인자가 와야 합니다. `##' 연산자 뒤에 인자가 오지 않을 때 이 에러가 발생합니다.

#define bug(s)        s ##

   

file:1: `##' at end of macro definition

   

`XXX' defined as wrong kind of tag

struct이나 union, enum을 써서 한 형을 만들때, 이 때 사용한 tag (예를 들어 struct s;에서 tag는 `s'가 됩니다.)가 다른 타입에서 쓰일 때 이 에러가 발생합니다.

struct s { int x, y, z; };

void f()

{

union s foo;

foo.x = 1;

}

   

file:4: `s' defined as wrong kind of tag

   

negative width in bit-field `XXX'

bit field에서 bit 갯수를 지정할 때 음수 [negative number]나 0을 쓸 수 없습니다.

struct s { int x : -3; };

   

file:1: negative width in bit-field `x'

   

warning: width of `XXX' exceeds its type

Bit field의 크기가 주어진 형의 크기를 넘을 경우 발생합니다. 크기가 큰 다른 형으로 바꾸거나 bit field의 크기를 줄여 해결할 수 있습니다.

struct s { char c : 20; };

   

file:1: warning: width of `c' exceeds its type

   

break statement not within loop or switch

`break' 키워드는 switch, while, do-while, for 내부에서만 쓰일 수 있습니다. `break'를 다른 곳에서 쓸 경우 이 에러가 발생합니다.

void f()

{

break;

}

   

file:3: break statement not within loop or switch

   

request for member `XXX' in something not a structure or union

`.' 연산자는 구조체 [structure]나 union에서 멤버 [member]를 엑세스하기 위해 사용하며, 구조체나 union이 아닌 곳에서 `.'를 사용할 경우에 이 에러가 발생합니다. 대개의 경우, 구조체의 이름을 틀리게 썼을 경우에 발생합니다.

struct s { int i; };

void f()

{

char c;

c.i = 3;

}

   

file:5: request for member `i' in something not a structure or union

   

char-array initialized from wide string

C 언어는 여러 나라의 언어를 지원하기 위해 multibyte 문자인 wide character를 지원합니다. Wide character 상수는 문자 상수나 문자열 앞에 'L'을 붙여 나타내며 이 형은 wchar_t (<stddef.h>에 정의되어 있습니다) 입니다. 이 에러는 wchar_t 형 문자열을 char 형 배열에 초기값으로 쓸 때 발생합니다. 배열을 wchar_t 형으로 선언하거나 초기값을 char 형 상수를 써서 이 에러를 해결할 수 있습니다.

char a[] = L"abc";

   

file:1: char-array initialized from wide string

   

declaration of `XXX' as array of voids

void 형은 포인터 형으로 쓰거나 함수의 return 값으로 쓰이는 경우에만 의미가 있습니다. 다른 경우, 예를 들어 void 형 배열을 선언하는 것은 옳지 않습니다.

void a[3];

   

file:1: declaration of `a' as array of voids

   

invalid macro name `defined'

프리프로세서 [preprocessor]의 연산자인 `defined'는 매크로 이름으로 정의될 수 없으며, 정의를 취소할 수도 없습니다.

invalid macro name `XXX' 에러를 참고하시기 바랍니다.

#undef defined

#define defined        abc

   

file:1: invalid macro name `defined'

file:2: invalid macro name `defined'

   

#undef 4

   

file:1: invalid macro name `4'

   

invalid type argument of `unary *'

단항 연산자 [unary operator] `*'는 포인터 앞에서 이 포인터가 가리키는 것을 역참조 [dereference]하기 위해 쓰입니다. `*' 연산자가 포인터가 아닌 다른 형에 쓰이면 이 에러가 발생합니다.

void f()

{

int i;

*i = 3;

}

   

file:4: invalid type argument of `unary *'

   

arithmetic on pointer to an incomplete type

아직 완전하게 정의가 알려지지 않은 형에 대해서 포인터 연산을 수행할 수 없습니다. 아래의 예에서 이 에러가 발생하지 않게 하려면 먼저 `struct s' 형의 정의를 내려야 합니다.

struct s;

void g(struct s*);

void f()

{

struct s *p;

g(p + 1);

}

   

file:6: arithmetic on pointer to an incomplete type

   

XXX: No such file or directory

`#include'에서 쓴 파일을 찾을 수 없을 때 이 에러가 발생합니다. 대개 이 에러는 사용자가 만든 파일을 `"' 대신 `<>'로 둘러싸거나 파일 이름을 틀리게 입력하거나, 또는 컴파일러 옵션에서 디렉토리 설정이 잘못되어 있는 경우, 컴파일러에서 쓰이는 환경 변수 [environment variable]가 잘못 지정되어 있는 경우에 발생합니다. 자세한 것은 GCC 문서(info)에서 `-I' 옵션이나 `C_INCLUDE_PATH' 환경 변수를 참고하시기 바랍니다.

#include <where_is_it.h>

   

file:1: where_is_it.h: No such file or directory

   

variable or field `XXX' declared void

변수나 field는 void 형으로 선언할 수 없습니다.

저자가 쓰고 있는 GCC 2.7.2는 전역 변수 [global variable]로 `void a;'를 선언하면 이 에러를 만들지 않습니다. 이는 버그인 것으로 생각되는데, 이 문제에 대해 도움을 주실 수 있는 분은 알려 주시면 감사하겠습니다. 연락처는 이 문서의 처음에 있습니다.

void foo()

{

void a;

}

   

file:3: variable or field `a' declared void

file:4: warning: unused variable `a'

   

`XXX' has both `extern' and initializer

함수의 내부에서 `extern'으로 선언된 오브젝트 [object]는 초기값 [initializer]을 가질 수 없습니다. `XXX' initialized and declared `extern' 경고를 참고하시기 바랍니다.

extern int i = 1;

void f()

{

extern int j = 3;

}

   

file:1: warning: `i' initialized and declared `extern'

file: In function `f':

file:4: `j' has both `extern' and initializer

tmp.c:4: warning: unused variable `i'

   

warning: `XXX' initialized and declared `extern'

`extern'으로 선언된 오브젝트 [object]에 초기값 [initializer]을 주면 `extern'은 무시됩니다. `XXX' has both `extern' and initializer 에러를 참고하시기 바랍니다.

extern int i = 1;

void f()

{

extern int j = 3;

}

   

file:1: warning: `i' initialized and declared `extern'

file: In function `f':

file:4: `j' has both `extern' and initializer

tmp.c:4: warning: unused variable `i'

   

function `XXX' is initialized like a variable

함수로 선언 [declaration]된 이름은 초기값 [initializer]을 가질 수 없습니다.

int f(void) = 3;

   

file:1: function `f' is initialized like a variable

   

parameter `XXX' is initialized

예전 방식 [old style]으로 선언된 함수에서 파라메터 [parameter]는 초기값 [initializer]을 가질 수 없습니다.

void f(i)

int i = 3;

{

}

   

file:2: parameter `i' is initialized

   

typedef `XXX' is initialized

`typedef'는 기존의 형에 대해 새 형 이름 [type name]을 정의하는 것이기 때문에 초기값 [initializer]을 가질 수 없습니다.

typedef int INT = 1;

   

file:1: typedef `INT' is initialized

   

No such file or directory

컴파일러가 주어진 파일 이름 (디렉토리 포함)을 찾을 수 없을 때 발생합니다. 대개 파일 이름을 틀리게 입력했을 때 발생합니다.

gcc where_is_it.c

   

where_is_it.c: No such file or directory

   

macro or `#include' recursion too deep

매크로나 `#include'가 재귀적으로 너무 깊게 반복될 때 발생합니다. 예를 들어 `util.h'가 `types.h'를 포함 (#include)하고, `types.h'가 다시 `util.h'를 포함하는 경우, 이들 파일을 소스에 포함시키면, 서로가 서로를 계속 포함시키게 되므로 결국 컴파일러는 이 에러를 발생시킵니다. 이럴 때에는 `#ifndef', `#define', `#endif' 등을 써서 재귀적으로 포함되지 않게 해서 해결합니다.

#include "util.h"

   

file:1: macro or `#include' recursion too deep

   

invalid use of undefined type `XXX'

주어진 형이 완전히 정의되지 않은 상태에서 이 형을 사용할 수 없습니다. 아래의 예에서는 함수 g()의 return 형이 `struct s'이지만 `struct s'는 아직 정의되지 않았습니다. 이 때 g()를 부르는 것은 옳지 않습니다. 이 문제를 해결하려면 함수 g()를 부르기 전에 먼저 `struct s'를 정의해야 합니다.

void f()

{

struct s g();

g();

}

   

file:4: invalid use of undefined type `struct s'

   

attempt to take address of bit-field structure member `XXX'

Bit field에는 `address of' 연산자인 `&'를 쓸 수 없습니다.

struct s { int i : 3; };

void f()

{

struct s p;

int *ip = &p.i;

}

   

file:5: attempt to take address of bit-field structure member `i'

file:5: warning: unused variable `ip'

   

warning: address of register variable `XXX' requested

`register'로 선언 [declaration]된 변수에 `address of' 연산자를 쓸 경우에 발생합니다. `register'를 쓴다고 항상 CPU의 레지스터에 이 변수가 저장되는 것은 아니지만, 실제 CPU 레지스터의 사용 여부에 상관없이 `register'를 쓴 변수의 주소를 얻는 것은 옳지 않습니다.

void f()

{

register int i;

int *ip = &i;

ip = 0;

}

   

file:4: warning: address of register variable `i' requested

   

`sizeof' applied to a bit-field

Bit-field에는 `sizeof' 연산자를 쓸 수 없습니다.

struct s { int i : 3; };

void f()

{

struct s p;

int i = sizeof(p.i);

i = 3;

}

   

file:5: `sizeof' applied to a bit-field

   

warning: case value out of range

`case'에서 쓴 상수식 [constant expression]은 `switch'에서 쓴 데이터 형의 범위를 넘을 수 없습니다. 아래의 예에서는 `case'의 상수식 0xffffff가 `char' 형의 범위를 넘었기 때문에 발생합니다. 이 문제를 해결하려면 `switch'에서 쓴 데이터의 형을 좀 더 큰 형 (예를 들어 `int')으로 바꾸어야 합니다.

void f()

{

char c;

switch (c) {

case 0xffffff:

;

}

}

   

file:5: warning: case value out of range

   

case label not within a switch statement

`case'는 `switch' 구조 안에서만 쓸 수 있습니다.

void f()

{

case 4:

;

}

   

file:3: case label not within a switch statement

   

character constant too long

정수안에 들어가기에는 너무 많은 문자를 가지고 있는 상수를 쓸 때에 이 에러가 발생합니다.

int i = 'abcde';

   

file:1: character constant too long

   

warning: escape sequence out of range for character

문자 상수나 문자열에 쓰인 escape sequence가 너무 큰 값을 가지고 있어 문자 [unsigned char]로 표현할 수 없을 때 이 경고가 발생합니다. 이러한 값들은 적절하게 잘라내 [truncate] 버립니다.

char *p = "\x1ff\400";

   

file:1: warning: escape sequence out of range for character

file:1: warning: escape sequence out of range for character

   

continue statement not within a loop

`continue' 키워드는 루프 [loop] (for, while, do-while) 안에서만 의미가 있습니다. `continue'를 루프 밖에서 쓰는 것은 옳지 않습니다.

void foo()

{

continue;

}

   

file:3: continue statement not within a loop

   

invalid operands to binary X

X는 바이너리 연산자 (예: +, -, *, /, ==, !=, <=, >= 등)이며, 연산자의 오퍼랜드 형은 스칼라 [scalar] 형이어야 합니다. 즉 정수나 실수이어야 하며, 구조체 [structure]나 union 형이 올 수 없습니다.

이 에러는 조건식 [conditional expression]이 필요한 if, for, while, do-while 등에서 구조체나 union형을 쓸 때에도 발생합니다.

또 이 에러는 형이 다른 포인터에 연산을 취할 때에도 발생할 수 있습니다.

struct s { int i; };

void f()

{

struct s p;

int i = (p != 0);

   

while (p) {

}

}

   

file: In function `f':

file:5: invalid operands to binary !=

file:7: invalid operands to binary !=

file:5: warning: unused variable `i'

   

void f()

{

char *cp;

int *ip;

int i;

i = ip - cp;

}

   

file: In function `f':

file:6: invalid operands to binary -

이 에러는 조건식인 `? :'을 쓸 때에도 발생합니다. 조건식 `e1 ? e2 : e3'는 `e1'이 참일 경우, `e2'가 평가되고, 거짓일 때에는 `e3'가 평가됩니다. 이 때 이 조건식은 `if (e1 != 0) e2 else e3'로 취급되므로 만약 `e1'이 스칼라 형이 아니면 이 에러가 발생합니다.

struct s { int x; } st;

   

void f(void)

{

int i = st ? 3 : 4;

}

   

file: In function `f':

file:5: invalid operands to binary !=

file:5: warning: unused variable `i'

   

warning: overflow in implicit constant conversion

주어진 상수를 함축적으로 [implicitly] 변환 [conversion]할 때 오버플로우 [overflow]가 발생할 때 이 경고가 발생합니다. 아래의 예는 `int' 형의 범위를 넘는 실수 상수 (double 형)를 `int' 형에 대입하려 하는 경우를 나타냅니다.

int i = 1e300;

   

file:1: warning: overflow in implicit constant conversion

   

warning: declaration of `XXX' shadows a parameter

함수 내부에서 이 함수에 전달되는 파라메터 [parameter]와 같은 이름을 선언한 경우에 발생합니다. 즉 파라메터의 이름이 새 선언 [declaration]에 의해 가려졌으므로 이 선언이 나온 다음부터는 이 이름을 가진 파라메터를 쓸 수 없습니다. 이 경우, 둘 중 하나를 다른 이름을 갖게 고치는 것이 좋습니다.

void f(int i, int INT)

{

int i;

i = 3;

}

   

file:3: warning: declaration of `i' shadows a parameter

   

warning: data definition has no type or storage class

데이터 (함수나 변수등)를 정의할 때 형을 쓰지 않을 경우 발생합니다. 일반적으로 함수나 변수의 return 형을 쓰지 않을 때 발생하며, 이 때에는 `int' 형으로 간주됩니다.

i;

f();

   

file:1: warning: data definition has no type or storage class

file:2: warning: data definition has no type or storage class

   

default label not within a switch statement

`default' 키워드는 `switch' 문 [statement] 안에서만 쓸 수 있습니다.

void f()

{

default:

;

}

file:3: default label not within a switch statement

   

invalid macro name `XXX'

매크로 이름은 유효한 [valid] C 언어 이름 [identifier]이 나와야 합니다. 즉 첫글자는 [_a-zA-Z]이며, 두번째 글자부터는 [_a-zA-Z0-9]입니다. 아래의 예에서 `3'은 이름 [identifier]이 될 수 없기 때문에 이 에러가 발생합니다.

invalid macro name `defined' 에러도 참고하시기 바랍니다.

#define 3

   

file:1: invalid macro name `3'

   

invalid format `#line' directive

`#line' 지시어 [directive] 뒤에는 라인 번호를 의미하는 수치가 나와야 합니다. 이 수치는 0이 아닌 양수 [positive number]이어야 합니다.

invalid #-line 에러를 참고하시기 바랍니다.

#line 02a

   

file:1: invalid format `#line' directive

   

warning: unknown escape sequence `\x'

문자열에서 `\' 뒤에 오는 문자는 특정한 뜻이 있는 몇 개의 문자만 쓸 수 있습니다. 예를 들어 `\n'은 newline 문자를 나타내고, `\t'는 tab 문자를 나타냅니다. 이를 `escape sequence'라고 하며, 알려지지 않은 문자가 `escape sequence'로 쓰인 경우 이 경고가 발생합니다. 이 때 쓰인 `\x'는 일반 문자 `x'로 취급됩니다.

int i = '\q';

   

file:1: warning: unknown escape sequence `\q'

   

duplicate case value

두 `case' 문장에서 같은 상수 값이 쓰였을 때 발생합니다.

void f()

{

int a = 3;

switch (a) {

case 1:

case 1:

default:

break;

}

}

   

file: In function `f':

file:6: duplicate case value

file:5: this is the first entry for that value

   

   

multiple default labels in one switch

`switch' 문장 안에서 `default' 레이블이 두 개 이상 쓰였을 경우 발생합니다.

void f()

{

int a = 3;

switch (a) {

case 1:

default:

default:

break;

}

}

   

file: In function `f':

file:7: multiple default labels in one switch

file:6: this is the first default label

   

duplicate member `XXX'

`struct'이나 `union'에서 같은 이름이 두 개 이상의 멤버에 쓰였을 때 이 에러가 발생합니다. 각각 다른 이름을 써서 이 에러를 없앨 수 있습니다.

struct s {

int i;

float i;

};

   

file:3: duplicate member `i'

   

`#elif' after `#else'

선택적 컴파일을 할 수 있는 `preprocessor directive'인 `#if', `#elif', `#else', `#endif'에서 `#elif'는 항상 `#else' 앞에 나와야 합니다.

#if defined(ONE)

int i = 1;

#elif defined(TWO)

int i = 2;

#else

int i = 3;

#elif defined(FOUR)

int i = 4;

#endif

   

file:7: `#elif' after `#else'

(matches line 1)

   

   

`#XXX' not within a conditional

`Preprocessor directive'인 `#else'나 `#elif'는 `#if'나 `#ifdef', `#ifndef' 등의 if 섹션의 일부로 쓰여져야 합니다. `#elif'가 단독으로 쓰였을 경우 이 에러가 발생합니다.

#elif defined(TWO)

int i = 2;

#endif

   

file:1: `#elif' not within a conditional

file:3: unbalanced `#endif'

   

   

#else

int i = 2;

#endif

   

file:1: `#else' not within a conditional

file:3: unbalanced `#endif'

   

   

invalid initializer

`struct'이나 `union'의 초기값을 중괄호({})로 싸지 않는 등, 잘못된 초기값을 썼을 때 이 에러가 발생합니다.

struct s {

int x;

int y;

} st = 1;

   

file:4: invalid initializer

   

enumerator value for `AA' not integer constant

Enumerator로 쓰일 수 있는 상수는 반드시 정수형 값을 가져야 합니다. 실수(real)나 다른 상수가 아닌 값이 쓰이면 이 에러가 발생합니다.

enum A { AA = 0.1, BB = 2 };

   

file:1: enumerator value for `AA' not integer constant

   

warning: parameter names (without types) in function declaration

함수의 선언은 ANSI 방식과 옛 방식 중 하나를 쓸 수 있습니다. 옛 방식은 함수의 인자 리스트를 쓰지 않고, ANSI 방식은 인자의 타입과 갯수를 꼭 지정해야 합니다. 아래의 예에서는 함수 f의 인자인 `i'의 타입을 지정하지 않았기 때문에 이 경고가 발생한 것입니다.

int f(i);

   

file:1: warning: parameter names (without types) in function declaration

   

undefined or invalid # directive

#abc

   

file:1: undefined or invalid # directive

   

invalid preprocessing directive name

# 0x12

   

file:1: invalid preprocessing directive name

   

   

conflicting types for `XXX'

int i;

long i;

   

file:2: conflicting types for `i'

file:1: previous declaration of `i'

   

   

redefinition of `XXX'

int i = 0;

int i = 1;

   

file:2: redefinition of `i'

file:1: `i' previously defined here

   

   

empty #if expression

#if

int i = 2;

#endif

   

file:1: empty #if expression

   

unterminated `#if' conditional

#ifdef A

int i = 1;

   

file:1: unterminated `#if' conditional

   

warning: `#ifdef' with no argument

#ifdef

int i = 1;

#endif

   

file:1: warning: `#ifndef' with no argument

   

#ifndef

int i = 1;

#endif

   

warning: implicit declaration of function `XXX'

void f()

{

g();

}

   

file:3: warning: implicit declaration of function `g'

   

void value not ignored as it ought to be

int f()

{

void g();

   

int i = (int)g();

return i;

}

   

file: In function `f':

file:5: void value not ignored as it ought to be

   

   

structure has no member named `XXX'

struct abc {

int a, b;

};

   

void f()

{

struct abc a;

a.c = 0;

}

   

cf. union도 같음

file: In function `f':

file:8: structure has no member named `c'

   

   

warning: initialization makes integer from pointer without a cast

int i = "abc";

   

file:1: warning: initialization makes integer from pointer without a cast

   

badly punctuated parameter list in `#define'

#define max(a

   

file:1: badly punctuated parameter list in `#define'

   

storage size of `XXX' isn't known

struct s st;

   

file:1: storage size of `st' isn't known

   

file:

   

file:

   

file:

   

file:

   

반응형

'Language > C' 카테고리의 다른 글

readv 함수 예제  (480) 2012.07.30
poll 함수 예제  (150) 2012.07.26
select 함수 예제  (167) 2012.07.23
Unix Domain Socket 예제  (165) 2012.07.23
semget. semop, semctl 함수 예제  (14) 2012.07.17

+ Recent posts