Search code examples
ctypesintunsignedsigned

Implicit conversion warning with own getch function


I found a c implementaion of conio.h's getch(). Sadly it compiles with a comversion warning, and i don't know what i should do to solve it correctly. I found this link, but i don't know how to implement it.

#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;
}

CLANG 3.5 returns:

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.

Solution

  • Due to integer promotions those defines are promoted to int, but the c_lflag member is an unsigned integer.

    Make sure the bitwise operation is done in an unsigned type:

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