Типичные предупреждения компилятора g++

(и как от них избавиться)


warning: comparison between signed and unsigned integer expressions
Появляется при попытке сравнить знаковое число с беззнаковым. Для избавления от предупреждения приведите обе части выражения к нужному типу.
Опасность ошибки показана во втором примере: a.size() - 1 в беззнаковом типе в случае пустого вектора будет равно 2^32 - 1, и цикл будет выполняться намного дольше, чем вы ожидаете.
Неправильно: Правильно:
void f(vector<int> a)
{
    for (int i = 0; i < a.size(); i++)
        cout << a[i] << endl;
}
void g(vector<int> a)
{
    for (int i = 0; i < a.size() - 1; i++)
        cout << a[i] << endl;
}
void f(vector<int> a)
{
    for (int i = 0; i < (int)a.size(); i++)
        cout << a[i] << endl;
}
void g(vector<int> a)
{
    for (int i = 0; i < (int)a.size() - 1; i++)
        cout << a[i] << endl;
}

warning: suggest parentheses around '&&' within '||'
Появляется, если не ставить скобки в нетривиальных логических выражениях. Несмотря на то, что приоритет операций в большинстве случаев однозначно определен, иногда выражение может вычисляться не так, как того ожидает программист.
Неправильно: Правильно:
if (a < b || c < d && e < f)
    ...
if (a < b || (c < d && e < f))
    ...
или
if ((a < b || c < d) && e < f)
    ...

warning: name lookup of 'i' changed
Появляется, если в данной области видимости есть несколько переменных с одинаковым названием. В разных стандартах компилятора по-разному указано, какую из них следует использовать.
Во вложенных циклах не следует использовать переменные с одинаковым названием. Кроме того, переменную, объявленную в цикле for, не следует использовать после выхода из цикла.
Неправильно: Правильно:
for (int i = 0; i < n; i++)
{
    for (int i = 0; i < m; i++)
        a[i] = 0;
    last = i;
}
for (int i = 0; i < n; i++)
{
    for (int j = 0; j < m; j++)
        a[j] = 0;
    last = i;
}

warning: suggest explicit braces to avoid ambiguous 'else'
В конструкции с сложным ветвлением условий недостаточно скобок.
Неправильно: Правильно:
if (x > 0)
    if (y > 0)
        f(1, 1);
    else
        f(1, -1);
 
if (x > 0)
{
    if (y > 0)
        f(1, 1);
    else
        f(1, -1);
}
 

warning: statement has no effect
warning: right operand of comma operator has no effect
Выражение ничего не делает.
Что делать? Исправить баг. Радоваться. Если вам действительно зачем-то понадобилась такая конструкция, обратитесь к психотерапевту преподавателю.
Неправильно: Правильно:
a == 4;
b = 3,5;
a = 4;
b = 3.5;

warning: control reaches end of non-void function
В функции, которая должна возвращать значение, одна из веток может не заканчиваться оператором return. Проверьте, что ветвление корректно. Если вы уверены, что при исполнении программы эта ветка никогда не будет выполнена, поставьте в конце assert(false).
Неправильно: Правильно:
int sqr(int x)
{
    if (x > 0)
        return x * x;
    if (x < 0)
        return (-x) * (-x);
}
int sqr(int x)
{
    if (x > 0)
        return x * x;
    if (x < 0)
        return (-x) * (-x);
    assert(false); // или return 0;
}