이 문서는 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: