C предупреждение (компилятор clang) "целочисленный литерал слишком велик, чтобы быть представленным в целом числе со знаком" - PullRequest
2 голосов
/ 20 февраля 2020

У меня есть этот кусок кода

#include <stdio.h>

typedef signed long long v2signed_long 
      __attribute__ ((__vector_size__ (sizeof(signed long long) * 2)));

int main()
{
        v2signed_long v = {4611686018427387904LL, -9223372036854775808LL};

        printf("%lli, %lli\n", v[0], v[1]);
        return 0;
}

, который выдает следующее предупреждение (связанные вопросы не помогли):

:7:45: warning: integer literal is too large to be represented in
       a signed integer type, interpreting as unsigned
  [-Wimplicitly-unsigned-literal]
    v2signed_long v = {4611686018427387904LL, -9223372036854775808LL};

Есть ли способ решить это предупреждение ? Спасибо!

Ответы [ 2 ]

10 голосов
/ 20 февраля 2020

Проблема в том, что -9223372036854775808LL на самом деле не является целочисленным литералом. Это литерал 9223372036854775808LL с примененным к нему унарным оператором -. Значение 9223372036854775808 слишком велико, чтобы поместиться в signed long long, поэтому вы получаете предупреждение.

Вы можете исправить это, используя вместо этого выражение -9223372036854775807LL - 1LL. Значение 9223372036854775807 вписывается в signed long long, как и -9223372036854775807LL, затем вычитая 1, вы получите желаемое значение.

В качестве альтернативы вы можете использовать макрос LLONG_MIN.

3 голосов
/ 20 февраля 2020

Компилятор считает эту конструкцию

-9223372036854775808LL

как целочисленный литерал 9223372036854775808LL, для которого применяется унарный оператор. Но значение 9223372036854775808 слишком велико для хранения в объекте типа, подписанного long long. Таким образом, компилятор выдает ошибку.

Вместо этого используйте

#include <limits>

//...

v2signed_long v = 
{
    std::numeric_limits<long long>::max(), std::numeric_limits<long long>::min()
};

Вот демонстрационная программа

#include <iostream>
#include <limits>
#include <vector>

int main() 
{
    std::vector<long long> v =
    {
        std::numeric_limits<long long>::max(), std::numeric_limits<long long>::min()
    };

    for ( const auto &item : v ) std::cout << item << '\n';

    return 0;
}

Его вывод

9223372036854775807
-9223372036854775808

Если вы удалили тег C ++, то в C код может выглядеть следующим образом:

#include <stdio.h>
#include <limits.h>

int main(void) 
{
    long long int a[] = { LLONG_MAX, LLONG_MIN };

    printf( "%lld\n%lld\n", a[0], a[1] );

    return 0;
}

Вывод программы такой же, как показано выше.

В любом случае, гораздо лучше использовать этот подход вместо магических c чисел с уловкой, которая только сбивает с толку читателей кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...