Difference between signed main() and int main()?

#include <bits/stdc++.h>
using namespace std;

#define int long long
typedef pair<int,int> pint;
typedef vector<int> vint;
typedef vector<pint> vpint;

#define rep(i,n) for(int i = 0; i < (n); i++)

int main()
{
    vint A(3), B(3);
    rep(i, 3) cin>> A[i];
    rep(i, 3) cin >> B[i];
    int pa = 0, pb = 0;
    rep(i, 3) {
        if(A[i] > B[i]) pa++;
        else if(A[i] < B[i]) pb++;
    }
    cout << pa << " " << pb << endl;
    return 0;
}

When using int main(), the compiler shows an error message "main must return int", but when I replace it with signed main(), there is no error. What's the reason?

3 answers

  • answered 2019-08-13 03:35 Igor Tandetnik

    int main doesn't return int - it returns long long. You have defined a macro named int.

    Speaking of which, defining a macro with the name that matches a keyword exhibits undefined behavior.

  • answered 2019-08-13 04:00 Mirko

    #define int long long
    

    Why on earth would you do that????

    typedef pair<int,int>pint;
    

    Don't do that. Type pair<int, int>; dont be lazy. Also, you're making the code convoluted just to define pint (which any reasonable person would assume "pointer to int") just not to use it.

    typedef vector<int>vint;
    typedef vector<pint>vpint;
    

    Ditto. Don't do that.

    #define rep(i,n) for(int i=0;i<(n);i++)
    

    No. No. Please, don't do that.

    int main()
    

    You defined int to be something else. You already broke C by this point.

    vint A(3),B(3);
    

    Please, take the time to type vector<int> instead of vint, and please, initialize each variable on its own line.

    rep(i,3)cin>>A[i];
    

    Does this seem clear to you? I don't even know if I want to know what it does. Don't use macros. Please.

    int pa=0,pb=0;
    

    Also, besides putting each initialization on its own line, and recall you defined int to be long long, please be consistent: A is a variable and you're naming it with capital letters, but here you're not using capital letters. Try to chose any rule you want, but be consistent. Like, "all clases with capital letters and all variables start with lowercase".

    Indent properly, please. And put some spaces, they don't charge you by character. If you can, put braces always. Instead of this:

    rep(i,3) {
        if(A[i]>B[i])pa++;
        else if(A[i]<B[i])pb++;
    }
    

    Just put this:

    for (int i= 0; i < 3; ++i) {
        if (A[i] > B[i]) {
            pa++;
        } else if (A[i] < B[i]) {
            pb++;
        }
    }
    

    Also, as A and B have size() member:

    for (size_t i= 0; i < min(A.size(), B.size()); ++i) {
        if (A[i] > B[i]) {
            pa++;
        } else if (A[i] < B[i]) {
            pb++;
        }
    }
    

    And in that way, if you change A(3) and B(3) to be A(5) and B(5), you don't have to search for the 3 in the for. Also, it would be better to have:

    static const auto n= 3;
    vector<int> A(n);
    vector<int> B(n);
    

    Assuming they always are going to be the same size.

    Spaces, pleaseeeeee:

    cout << pa << " " << pb << endl;
    

  • answered 2019-08-13 04:16 Jmin17

    In general, you don't want to #define stuff that will be used in your code, as it can cause unforeseen issues resulting in errors. Something I commonly come across is:

    #define max(a,b)(a<b?a:b)
    

    which prevents anyone from writing a function named 'max' in any of the code following that definition.