Thread: warning: comparison between signed and unsigned - K&R program

  1. #1
    Registered User
    Join Date
    Nov 2015
    Posts
    54

    warning: comparison between signed and unsigned - K&R program

    Hi!

    When I try to compile the program from K&R (using -Werror -Wall -Wextra -pedantic), I get this warning (the full program is below):
    warning: comparison between signed and unsigned

    which refers to this line:

    Code:
    for (n = 0; n < NKEYS; n++)
    I see that I have declared n as an int, and NKEYS is an unsigned type.
    But I can't change n for sure, because binsearch function might
    return -1, hence I need signed int.
    As to NKEYS, sizeof returns size_t value, which is, as said in K&R,
    is an unsigned type.

    I wonder why this error occurs in code from K&R and they do not refer
    to it. Is there a way to overcome this issue?
    Code:
    /* Program to count the occurences of each C keyword */
    #include <stdio.h>
    #include <ctype.h>
    #include <string.h>
    #include <stddef.h>
    
    struct key
    {
        char *word;
        int count;
    } keytab[] =
    {
        {"auto", 0},
        {"break", 0},
        {"case", 0},
        {"char", 0},
        {"const", 0},
        {"continue", 0},
        {"default", 0},
        /* ... */
        {"unsigned", 0},
        {"void", 0},
        {"volatile", 0},
        {"while", 0}
    };
    
    #define MAXWORD 100
    #define NKEYS (sizeof keytab / sizeof(struct key))
    /* same as #define NKEYS (sizeof keytab / sizeof keytab[0]) */
    
    int getword(char *, int);
    int binsearch(char *, struct key *, int);
    
    /*count C keywords */
    int main(void)
    {
        int n;
        char word [MAXWORD];
        
        while (getword(word, MAXWORD) != EOF)
        {
            if (isalpha(word[0]))
            {
                if ((n = binsearch(word, keytab, NKEYS)) >= 0)
                {
                    keytab[n].count++;
                }
            }
        }
        
        for (n = 0; n < NKEYS; n++)
        {
            if (keytab[n].count > 0)
            {
                printf("%4d %s\n",
                       keytab[n].count, keytab[n].word);
            }
        }
        return 0;
    }
    /* GETCH and UNGETCH functions */
    
    #define BUFSIZE 100
    
    /* buffer for ungetch */
    static char buf[BUFSIZE];
    
    /* next free position in buf */
    static int bufp = 0;
    
    /* get a (possibly pushed back) character */
    int getch (void)
    {
        return (bufp > 0) ? buf[--bufp] : getchar();
    }
    
    /* push character back on input */
    void ungetch (int c)
    {
        if (bufp >= BUFSIZE)
        {
            printf("ungetch: too many characters\n");
        }
        else
        {
            buf[bufp++] = c;
        }
    }
    
    /* getword: get next word or characer from input */
    int getword (char *word, int lim)
    {
        int c, getch(void);
        void ungetch(int);
        char *w = word;
        
        while (isspace(c = getch ()))
            ;
        if (c != EOF)
        {
            *w++ = c;
        }
        if (!isalpha(c))
        {
            *w = '\0';
            return c;
        }
        for ( ; --lim > 0; w++)
        {
            if (isalnum(*w = getch()))
            {
                ungetch(*w);
                break;
            }
        }
        *w = '\0';
        return word[0];
    }
    
    /* binsearch: find word in tab[0] ... tab[n-1] */
    int binsearch(char *word, struct key tab[], int n)
    {
        int cond;
        int low, high, mid;
        
        low = 0;
        high = n - 1;
        while (low <= high)
        {
            mid = (low + high) / 2;
            if ((cond = strcmp(word, tab[mid].word)) < 0)
            {
                high = mid - 1;
            }
            else if (cond > 0)
            {
                low = mid + 1;
            }
            else
                return mid;
        }
        return -1;
    }

    Thank you!

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Ducol
    I see that I have declared n as an int, and NKEYS is an unsigned type.
    But I can't change n for sure, because binsearch function might
    return -1, hence I need signed int.
    You can still use an unsigned integer type because -1 will be converted to the largest value for the given unsigned integer type. So, you could change the count member to be a size_t, change the n local variable to be a size_t, and change binsearch to return a size_t.

    Quote Originally Posted by Ducol
    I wonder why this error occurs in code from K&R and they do not refer
    to it.
    It is not an error; it is a warning indicating that there could be a bug. Or not.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Nov 2015
    Posts
    54
    Quote Originally Posted by laserlight View Post
    You can still use an unsigned integer type because -1 will be converted to the largest value for the given unsigned integer type. So, you could change the count member to be a size_t, change the n local variable to be a size_t, and change binsearch to return a size_t.


    It is not an error; it is a warning indicating that there could be a bug. Or not.
    Thank you for your reply. Unfortunately, this doesn't solve the issue. Yes, before posting my question, I have tried to change types to unsigned and size_t.
    Both didn't work, because compiler produces an understandable warning:
    warning: comparison of unsigned expression >= 0 is always true

    I am new to programming, and might miss important details.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    That warning is a valid one: you need to change how to detect "not found" when you change the function's return type to size_t.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Nov 2015
    Posts
    54
    Quote Originally Posted by laserlight View Post
    That warning is a valid one: you need to change how to detect "not found" when you change the function's return type to size_t.
    I see, I have to change return -1 to some value appropriate for size_t. Thank you!

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Ducol
    I have to change return -1 to some value appropriate for size_t.
    Yes, but of course this is quite simple: just cast -1 to size_t.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 19
    Last Post: 09-25-2014, 10:02 PM
  2. Signed Long comparison in IF Statement
    By dcwang3 in forum C Programming
    Replies: 21
    Last Post: 04-25-2013, 02:01 PM
  3. Signed and unsigned
    By ncode in forum C Programming
    Replies: 3
    Last Post: 09-02-2011, 08:59 PM
  4. signed or unsigned?
    By ulillillia in forum C Programming
    Replies: 7
    Last Post: 05-08-2007, 01:06 AM
  5. MSVC Signed/Unsigned Warning
    By Sentral in forum C++ Programming
    Replies: 8
    Last Post: 10-17-2006, 01:31 PM

Tags for this Thread