2014-05-23 4 views
2

변수 유형에 따라 0xff가 다른 표현을 가질 수 있다는 것을 알고 있습니다. signed (chars/ints (?))는 -1, unsigned chars는 255와 같습니다.' xff'이 인식되지 않는 이유는 무엇입니까?

하지만 구현 독립적 인 유형의 uint8_t를 사용하고 있으며 0xff가 실제로 반복되는 구조 내부에 있는지 확인했습니다. 코드는 다음과 같습니다.

struct pkt { 
    uint8_t msg[8]; 
}; 

void main(int argc, char **argv) { 
    ... 

    struct pkt packet; 
    memset(&packet, 0, sizeof packet); 
    strcpy(packet.msg, "hello"); 
    packet.msg[strlen("hello")] = '\xff'; 

    crypt(&packet, argv[1]);  

    ... 
} 

void crypt(struct pkt *packet, unsigned char *key) { 
    int size = msglen(packet->msg); 

    ... 
} 

int msglen(uint8_t *msg) { 
    int i = 0; 
    while(*(msg++) != '\xff') { 
     i++; 
    } 
    return i; 
} 

구조를 살펴본 결과 packet.msg [5]는 실제로 0xff로 설정되었습니다. 그러나 while 루프는 0xff를 발견하지 못했던 것처럼 무한 루프로 진행됩니다.

0x7f와 같은 값이 작동합니다. 나는 0x80을 시도하지 않았지만 0xff가 그렇지 않으면 아마 작동하지 않을 것이라고 생각한다. 아마도 서명과 관련이 있을지 모르지만 문제가 어디에서 발생했는지는 알 수 없습니다.

감사합니다.

EDIT : 0x7f 또는 0xff를 사용하면 나에게 문제가되지 않습니다. 그러나 나는 0xff를 탐지하지 못하게하는 것이 무엇인지 알고 싶습니다.

+1

'while (* (msg ++)! = (uint8_t) '\ xff') {' –

+0

'main'은'void'가 아닌'int'를 반환합니다. –

+1

그리고'-Wall -Wextra'를 활성화하면 문제의 라인에서 "signed and unsigned 비교"경고가 나타납니다. –

답변

4

서명이없는 경우 문자 리터럴을 사용할 수 없습니다.

'\ xff'은 문자 리터럴에 서명되어 있기 때문에 -1이 아닌 255입니다.

while 조건은 항상 true입니다. 서명하지 않은 경우 숫자 만 사용해야합니다 (0에서 255까지). 또는 알고있는 캐스팅 문자는 < 128에서 서명하지 않아야합니다.

+2

' '\ xff'는 문자열 상수이며 문자열 리터럴은 아닙니다. 문자열 리터럴에는 서명이 없습니다. 그들은 배열을 나타냅니다. 'char' 유형은 구현에 따라 부호가 있거나 부호가 없습니다. 일반'char'이 부호없는 경우' '\ xff'는 'int'형 255 값을가집니다. 평범한'char'이 서명 되었다면, 표준의 표현은 (적어도 저에게) 불분명합니다. –

+1

대답의 일반적인 성격은 올바른 방향이지만 진술에는 오류가 있습니다. -1. –

+0

예 - 문자열 리터럴이 아닌 리터럴 값을 의미했습니다. Keith는 '배열을 나타냄'이란 무엇을 의미합니까? 또한 C 표준은 int (부호있는 int)이어야하며 signed 또는 unsigned char에 대해서는 아무 것도 말하지 않는다고 말합니다. – Myforwik

4

\xff은 문자 상수입니다. int이 아니고 char이 아니지만 (이는 C가 C++과 다른 방법입니다), 그 값은 일반 정의 char이 구현 정의되어 있는지 여부에 따라 달라집니다.

C 표준의 표현은 다음과 같습니다

백 슬래시와 문자 A 진수 이스케이프 시퀀스에서 x에 따라 16 진수 숫자는 단일 문자의 건설 의 일부가 촬영 정수 문자 상수 또는 와이드 문자 상수에 대해 단일 문자 와이드 문자. 이와 같이 형성된 16 진수 인 의 숫자 값은 원하는 문자 또는 와이드 문자 의 값을 지정합니다. char 일반 서명되지 않은 경우

'\xff'0xff 또는 255에 해당; 형식은 int이고 값은 255입니다. char 일반 서명되면

'\xff'char의 범위 (char가 8 비트라고 가정하면) 외측의 값을 지정한다. 표준의 문구는 100 % 명확하지 않지만 최소한 '\xff'의 값은 -1입니다.

문자 상수 \xff' 대신 정수 상수 0xff을 사용하십시오.0xffint 유형이며 원하는 값인 255입니다.

2

저는 0xff가 변수 유형에 따라 다른 표현을 가질 수 있다는 것을 알고 있습니다. signed (chars/ints (?))는 -1, unsigned chars는 255와 같습니다.

설명이 필요합니다. C 프로그램의 정수 리터럴 0xFF은 항상 255을 의미합니다. 255이 범위를 벗어나는 유형 (예 : a signed char 그러면 동작은 구현에 따라 정의됩니다. 일반적으로 2의 보수 시스템에서 이것은 -1 값을 할당하는 것으로 정의됩니다.

문자 리터럴은 정수 리터럴과 다른 규칙을가집니다. 문자 리터럴 '\xff'char에 앉을 수있는 값이어야합니다. char에 서명 한 것처럼 보입니다. 구현 정의에 따라 여기에서 발생하지만, 가장 일반적인 동작은 값이 -1 인 것입니다. 문자 리터럴은 char으로 표현할 수있는 값을 가져야한다는 사실에도 불구하고 실제로 문자 리터럴 형식이 int입니다.

packet.msg[strlen("hello")] = '\xff'; 줄에서 (int)-1uint8_t에 할당하려고합니다. 이것은 범위를 벗어 났지만, 서명 된 유형에 대한 범위를 벗어난 할당에 대해서는 잘 정의되어 있으므로 -1 (mod 256)255입니다.

마지막으로 == 연산자 (및 대부분 연산자)를 사용하면 값이 int (아직 정수가 아닌 경우)로 승격됩니다. 8 비트 int 255(int)255으로 승격되며 이것을 (int)-1과 비교하면 서로 다릅니다.

이 문제를 해결하려면 0xFF 또는 (uint8_t)'\xFF' 중 하나를 사용하십시오.

관련 문제