Ошибка в троичном операторе "C" для возврата значения - PullRequest
0 голосов
/ 20 апреля 2020

Я сделал этот код, чтобы найти значение с помощью алгоритма экспоненциального поиска

int exponential_search(int *array, size_t size, int value)
{
    size_t m = 1;
    size_t limit = 0;
    int out = 0;

    if (!array)
        return (-1);

    while (m < size && array[m] <= value)
    {
        printf("Value checked array[%ld] = [%d]", m, array[m]);
        m *= 2;
    }

    limit = (m < size) ? (m / 2) + 1 : size - (m / 2);
    out = binary_search(&array[m / 2], limit, value);

    return (out != -1) ? out + (m / 2) : -1;
}

Когда я скомпилировал его, используя gcc -Wall -Wextra -Werror -pedantic, я получил это сообщение об ошибке:

error: signed and unsigned type in conditional expression [-Werror=sign-compare]
  return (out != -1) ? out + (m / 2) : -1;
                                     ^
cc1: all warnings being treated as errors

Я не могу понять, почему

Когда я изменяю «-1» на «1», это работает, но мне нужно вернуть «-1», кроме того, я не хочу использовать оператор if / else if возможно

1 Ответ

0 голосов
/ 20 апреля 2020

Предупреждение / ошибка, которую вы видите, состоит в том, что второй и третий операнды троичного оператора имеют другой тип, приводящий к преобразованию.

Второй операнд out + (m / 2) имеет тип size_t, потому что это тип m, который выполняет остальную часть выражения. Третий операнд -1 имеет тип int. Поскольку оператор ?: может приводить только к одному типу, тогда как обычные арифметические преобразования c применяются к обоим для определения типа.

Поскольку size_t, который является беззнаковым, по меньшей мере равен int, третий операнд преобразуется в size_t. Это означает, что значение -1 преобразуется в значение без знака, результатом которого будет очень большое положительное число (скорее всего, 2 64 - 1).

Причина, по которой вы не эта ошибка появляется, когда третий операнд равен 1, потому что преобразование значения int 1 в size_t не изменит его значение, поскольку оно находится в диапазоне size_t, тогда как -1 is not.

Вы можете предотвратить это преобразование, приведя m к int. В результате второй операнд будет иметь тип int, поэтому третий операнд не будет преобразован.

return (out != -1) ? out + ((int)m / 2) : -1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...