Dreamvillain
Dreamvillain

Reputation: 5

C++ not sure how to fix C4018 unsigned int mismatch

relatively new to C++ and I'm having issues getting my code going. When I compile and run the program the terminal window is just black, but I noticed 3 warnings I have might be causing this issue, however I'm not sure how to clear them up.

The errors are the following, all stated to be in the .cc file:


    Line 31 Warning C4018    '<': signed/unsigned mismatch  
    Line 60 Warning C4018    '<': signed/unsigned mismatch  
    Line 57 Warning C4018    '>=': signed/unsigned mismatch

Here is the header file to my program:


    #ifndef H_JOSEPHUS
    #define H_JOSEPHUS
    
    #include <iostream>
    #include <sstream>
    #include <string>
    #include <list>
    #include <algorithm>
    
    using namespace std;
    
    #define NO_LETS  26    // no of letters in English alphabet
    #define NO_ITEMS 12    // no of items printed on single line
    
    // struct for input arguments
    
    struct args {
        unsigned N,       // no of initial people   
                 M,       // count to eliminate person
                 K;       // frequency of printouts
    };
    
    // class to generate name tags for people
    
    class SEQ {
    private:
        string id;         // name tag for person
        unsigned size, nd; // no of people, no of digits in name tags
    
        // returns no of digits in name tags
        unsigned find_nd ( const double& sz ) {
            if ( ( sz / NO_LETS ) <= 1 ) return 2;
            else return ( find_nd ( sz / NO_LETS ) + 1 );
        }
    
    public:
        // constructor for name-tag generator
        SEQ ( const unsigned& s = 1 ) : size ( s ) {
            double sz = ( double ) size / 9; nd = find_nd ( sz );
            id = string ( nd, 'A' ); id [ nd - 1 ] = '1'; 
        }
    
        // returns next name tag in sequence
        string operator ( ) ( ) {
            string tmp = id; int i = nd - 1;
            if ( id [ i ] < '9' ) id [ i ]++;
            else {
                id [ i ] = '1'; bool flag = true;
                for ( i--; i >= 0 && flag; i-- )
                    if ( id [ i ] < 'Z' ) { id [ i ]++; flag = false; }
                    else id [ i ] = 'A';
            } 
            return tmp;
        }
    };
    
    // reads and initializes all input arguments
    void init_vals(list<string>& L, args& in);
    
    // prints all name tags for remaining people after elimination
    void print_list ( const list < string >&, const unsigned& );
    
    #endif

Here is my .cc file:


    #include "josephus.h"
    #include <iostream>
    using namespace std;
    
    int M;
    int K;
    void prnt(list < string >& L)
    {
        int c = 1;
        int i = 0;
        for (list<string>::iterator it = L.begin(); it != L.end(); it++)
        {
    
            cout << *it << " ";
            if (c == 12)
            {
                c = 1; cout << "\n";
            }
            c++;
    
    
        }
        cout << "\n";
    }
    
    void init_vals(list<string>& L, args& in)
    {
        cin >> in.N >> in.M >> in.K;
        cout << "\nThe values of n m k are: " << in.N << " " << in.M << " " << in.K;
        list<string>::iterator it;
        for (int i = 0; i < in.N; i++) // line 31
        {
            string s;
            stringstream ss;
            ss << char('A' + i / 9);
            ss >> s;
            s += char(((i + 1) % 9) + '0');
            L.push_back(s);
            //cout<<L[i]<<" ";
        }
    }
    
    void print_list(const list<string>&L, const unsigned&cnt)
    {
        cout << "\nAt begining of the joseph problem\n";
        //bool arr[L.size()]={true};
        list < string > l = L;
        prnt(l);
        int counter = 0;
        int sz = L.size() - 1;
        int c = cnt;
        while (c < sz)
        {
    
    
            counter += M - 1;
            if (counter >= l.size()) counter %= l.size(); // line 57
            list<string>::iterator it = l.begin();
            //it = it
            for (int i = 0; i < static_cast<unsigned int>(counter); i++) // line 60
                it++;
            l.erase(it);
            c++;
            if ((c) % K == 0)
            {
                cout << "\n After deleting K name\n";
                prnt(l);
            }
        }
        cout << "\nLast remaining person: " << *(l.begin());
    }
    
    int main()
    {
        list<string> L;
        struct args in;
        init_vals(L, in);
        M = in.M;
        K = in.K;
        print_list(L, 0);
    
    }

Any guidance is greatly appreciated!

Upvotes: 1

Views: 138

Answers (2)

Clifford
Clifford

Reputation: 93496

All the warnings are trivial type mismatches and the cause of your program failing to output.

  • At for (int i = 0; i < in.N; i++) args::N is unsigned while i is int.
  • At if (counter >= l.size()) counter %= l.size(); counter is int while std::list::size()returns an unsigned type.
  • At for (int i = 0; i < static_cast<unsigned int>(counter); i++) i is int and you have bizarrely force a type disagreement by casting counter.

Fixing the warnings is a simple matter of not comparing signed to unsigned types. I get an additional warning - the variable i in prnt() is unused.

Running the code, it waits for input at:

    cin >> in.N >> in.M >> in.K;

I entered 1 2 3, and it output:

The values of n m k are: 1 2 3                                                                                             
At begining of the joseph problem                                                                                          
A1

Perhaps the only problem is it is waiting for input that you are not providing - a user prompt might be in order.

You might also use a debugger - when your code stalls like this you can interrupt its execution and see where it is in the code.

Upvotes: 0

Govind Parmar
Govind Parmar

Reputation: 21562

in::N is declared as unsigned here:

struct args {
        unsigned N,       // no of initial people   
                 M,       // count to eliminate person
                 K;       // frequency of printouts
    };

You declare your loop variable as a plain (i.e. signed) int in

for (int i = 0; i < in.N; i++)

And std::list::size is unsigned yet you compare it with the signed int counter here:

if (counter >= l.size()) counter %= l.size();

Upvotes: 1

Related Questions