Signed Character FAQ #
DISCLAIMER: All information given here is believed to be correct, but is subject to change at any time. However, I assume no responsibility for any errors, omissions, consequences or damages caused by the application or use of the information within this document.
근래에 linux-arm 메일링 리스트에 나타나는 다음 email 일부이다.
> consider this simple program:
> int main(void)
> {
> char i = -1;
> printf("%d\n", i);
> return 0;
> }
>
> The print out is 255 in stead of -1, unless I define i as
> signed char i;
> then I get the "-1" print out.
위의 코드는 확실히 버그가 있다. 그것은 "char"가 "signed char"형과 동일 할 것이라는 가정을 하고 있는 것이다. C 표준에서 말하는 "char"는 "signed char" 이거나 "unsigned char" 둘다가 될 수 있고 그것은 컴파일러의 구현이나 플렛폼에 따라 정해진다.
게시된 것이 지적하듯이, "char"가 "unsigned"라면 위의 코드는 예상하듯이 동작하지 않을 것이다. GCC가 어떠한 경고 메시지도 발생하지 않는다면, 컴파일 시에 이 코드를 찾아내는 것(to detect)은 어렵다. 이것을 찾는 유일한 방법은 코드를 직접 눈으로 판독(visual examination)하거나, 실제로 동작시켜 문제를 찾는 방법이외엔 없다.
이것은 컴파일러가 빠르고 좀 더 효율적인 코드를 생성하기 위한 방법으로 "char"를 "unsigned" 형으로 변화시킨 ARM based machines에 문제의 원인이 된다. ARM이 이러한 문제에 유일한 존제가 아니라, IRIX가 도는 SGI MIPS 또한 이러한 문제를 맞닥드리고 있다.
아무리 위와 같은 경우에 경고 메시지를 내지 않는다 할지라도, GCC는 다음과 같은 경우 경고를 해준다.
{
char foo;
foo = bar();
if (foo == -1) {
...
}
}
위와 같은 코드는 컴파일러 경고를 발생하며, 실제 테스트에 사용되는 것에 따라 다음의 메시지 중에 하나를 볼 수 있다.
warning: comparison is always 0 due to limited range of data type
warning: comparison is always 1 due to limited range of data type
그러나 위의 경고가 "char"가 "signed" 형인 경우엔 발생하지 않으며, 그러면 그러한 환경에서의 컴파일 시엔 찾아내기가 힘들어 질 수 있다는 것을 상기해야 한다.
다음 표에서 변수 "c" 가 단지 "char"형으로 선언되었을때 문제를 야기시키는 네 종류의 형태를 나열하고 있고, 가장 정확한 방법으로 수정할 수 있는 코드를 보여준다.
| Code | Correction | Reasoning |
1 | c=getopt() | declare c as an "int" | getopt() is defined as returning an "int" not a "char" |
2 | c=getc() | declare c as an "int" | getc() is defined as returing an "int" not a "char" |
3 | c==EOF | declare c as an "int" | EOF is a "negative integral constant" |
4 | c < 0, c >= 0 | declare c as an "int or "signed char" | this is ambiguous and examination of the surrounding code should indicate which case is more correct. However, "int" is the perferred, unless the code is relying on some characteristic of "signed char" |
NOS(Not Otherwise Specified) 1, 2 와 3은 signed char 환경에서도 문제를 일으킬 수 있다. byte 값 0xff를 갖는 파일의 instance를 택해라.
(Nos 1, 2 and 3 can cause problems even in a signed char environment. Take the instance of a file containing a byte value 0xff.)
Last modified: May 12, 2000
Russell King
Translated by: Duke Cho (Oct. 10, 2005.)