2016-07-04 2 views
0

conio.h의 getch() 구현을 발견했습니다. 슬프게도 그것은 유쾌한 경고와 함께 컴파일하고, 나는 그것을 올바르게 해결하기 위해 무엇을해야하는지 모른다. this 링크를 찾았지만 구현 방법을 모르겠습니다.자신의 getch 함수를 사용한 암시 적 변환 경고

#include<termios.h> 
#include<unistd.h> 
#include<stdio.h> 
#include"getch.h" 

/* reads from keypress, doesn't echo */ 
int getch(void) 
{ 
    struct termios oldattr, newattr; 
    int ch; 
    tcgetattr(STDIN_FILENO, &oldattr); 
    newattr = oldattr; 
    newattr.c_lflag &= ~(ICANON | ECHO); 
    tcsetattr(STDIN_FILENO, TCSANOW, &newattr); 
    ch = getchar(); 
    tcsetattr(STDIN_FILENO, TCSANOW, &oldattr); 
    return ch; 
} 

/* reads from keypress, echoes */ 
int getche(void) 
{ 
    struct termios oldattr, newattr; 
    int ch; 
    tcgetattr(STDIN_FILENO, &oldattr); 
    newattr = oldattr; 
    newattr.c_lflag &= ~(ICANON); 
    tcsetattr(STDIN_FILENO, TCSANOW, &newattr); 
    ch = getchar(); 
    tcsetattr(STDIN_FILENO, TCSANOW, &oldattr); 
    return ch; 
} 

꽝 3.5 반환 :

getch.c:13:24: warning: implicit conversion changes signedness: 'int' to 'unsigned int' [-Wsign-conversion] 
    newattr.c_lflag &= ~(ICANON | ECHO); 
        ~~ ^~~~~~~~~~~~~~~~~~ 
getch.c:27:24: warning: implicit conversion changes signedness: 'int' to 'unsigned int' [-Wsign-conversion] 
    newattr.c_lflag &= ~(ICANON); 
        ~~ ^~~~~~~~~~~ 
2 warnings generated. 
+0

이 전체 경고와 함께'gcc' 또는'clang' 중 하나와 리눅스에서 깨끗하게 컴파일합니다. 꽤 표준적인 관용어입니다 (즉, 유닉스/SysV/등으로 거슬러 올라가 꽤 오래 동안 일해 왔습니다). 어떤 OS/배포판과 컴파일러 버전입니까? 또한, c_lflag, ICANON 등의 정확한 정의는 무엇입니까? –

+0

@CraigEstey 다음은 정의가 서명 된 것으로 정의 된 한 예입니다. http://www.delorie.com/djgpp/doc/incs/termios.h – 2501

+0

@CraigEstey 데비안 8 (Clang3-5 및 3-8, -pedantic 포함) -Wall -Weverything – vortexman100

답변

1

인해 정수 프로모션에 그 정의는 int로 승진하지만 멤버 인 c_lflag는 부호없는 정수입니다.

은 비트 연산이 부호없는 형식에서 수행되어 있는지 확인합니다 :

newattr.c_lflag &= ~(0u | ICANON | ECHO); 
         ^ 
+0

은'ICANON'과'ECHO'의 너비에 따라'0ul' 또는'0ull' 일 필요가 있습니다 –

+0

@ M.M 더 넓은 타입을 강제해서는 안됩니다. 필요한 경우 자동으로 승격됩니다. – 2501

+0

ITYM이 변환 됨. 피연산자가'unsigned int'와'long' (그리고'long'이'int'보다 길면) 결과는 부호없는 long이 아닌'long'입니다. –