long не равен другому long в C ++

0

Он никогда не появляется в статусе if, когда, очевидно, 0 == 0 sizeof() обеих функций возвращает long и regular long, как говорят 8, я не знаю, что еще может быть неправильно здесь.

Объявления:

long                        RemoteStep; // Next packet number to-be-processed

long GetLong(BYTE * Message, const SHORT Offset)
{   // Get a long from a char *
    return *(long*)&(Message[Offset]);
}

Код отладки:

printf("id = %d  remotestep = %d \n", GetLong(Packet->Message, 2), RemoteStep);
printf("id = %d  remotestep = %d \n", GetLong(Packet->Message, 2), RemoteStep);
printf("id = %d  remotestep = %d \n", GetLong(Packet->Message, 2), RemoteStep);
printf("equals = %d \n", GetLong(Packet->Message, 2) == RemoteStep);
printf("sizeof = %d - %d\n", sizeof(GetLong(Packet->Message, 2)), sizeof(RemoteStep));
        // Process if expected
        if (GetLong(Packet->Message, 2) == RemoteStep)
        {
            printf("in.............\n");
            ...
        }

Выходная информация:

id = 0  remotestep = 0
id = 0  remotestep = 0
id = 0  remotestep = 0
equals = 0
sizeof = 8 - 8
id = 1  remotestep = 0
id = 1  remotestep = 0
id = 1  remotestep = 0
equals = 0
sizeof = 8 - 8

Я скомпилировал это в g++34 compat-gcc-34-c++ aka g++34, я не могу использовать новые компиляторы g++, поскольку они дают слишком много предупреждений и даже ошибок.

с -Wall -Wextra

declares.h:1880: warning: int format, different type arg (arg 2)
declares.h:1880: warning: int format, different type arg (arg 3)
declares.h:1880: warning: unknown conversion type character 0x20 in format
declares.h:1880: warning: unknown conversion type character 0x20 in format
declares.h:1880: warning: too many arguments for format
declares.h:1881: warning: unknown conversion type character 0x20 in format
declares.h:1881: warning: unknown conversion type character 0x20 in format
declares.h:1881: warning: too many arguments for format
declares.h:1882: warning: unknown conversion type character 0x20 in format
declares.h:1882: warning: unknown conversion type character 0x20 in format
declares.h:1882: warning: too many arguments for format
declares.h:1884: warning: int format, different type arg (arg 2)
declares.h:1884: warning: int format, different type arg (arg 3)

строка 1880 является одной из

printf("id = %l  remotestep = %l \n", GetLong(Packet->Message, 2), RemoteStep);
  • 0
    Включите предупреждения компилятора ( -Wall -Wextra ).
  • 4
    Печать long строки с использованием %d имеет неопределенное поведение, хотя это может и не быть причиной проблемы.
Показать ещё 12 комментариев
Теги:
long-integer

2 ответа

2
Лучший ответ

long тип не должен печататься с %d, это явно не определено в спецификации. Например,

Каждая спецификация преобразования вводится символом "%"...
...
Если спецификация преобразования не соответствует одной из вышеуказанных форм, поведение не определено. Если какой-либо аргумент не является правильным типом для соответствующей спецификации преобразования, поведение не определено. http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html

(документация относится к printf а также fprintf)


Таким образом, вы не можете полагаться на вывод,

printf("id = %d  remotestep = %d \n", GetLong(Packet->Message, 2), RemoteStep);

чтобы определить, что

printf("equals = %d \n", GetLong(Packet->Message, 2) == RemoteStep);
//output: equals = 0

на самом деле неверно, и вам сначала нужно исправить свои отладочные заявления:

printf("id = %ld  remotestep = %ld \n", GetLong(Packet->Message, 2), RemoteStep);

В вашем случае также предпочтительнее использовать memcpy вместо memcpy указателя,

long GetLong(BYTE * Message, const SHORT Offset)
{   
    long result;
    std::memcpy(&result, &(Message[Offset]), sizeof(long)); 
    return result;
}

так как long* может иметь более строгие требования к выравниванию на вашей платформе, чем char*.

  • 0
    хе-хе, ты имеешь в виду %ld : P хаха та же ошибка
  • 0
    :) да, уже поздно, исправлено, между прочим, я думаю, что Майк Сеймур прав (и он должен дать ответ, если вы подтвердите), вам нужно убедиться, что вы хотите прочитать 8 байтов.
Показать ещё 8 комментариев
0

Вы можете изменить свои утверждения для использования std :: cout вместо printf, так как вы отметили вопрос с помощью C++, а не с C. В cout вы не получите этих удивительных эффектов% d или других спецификаторов% во время выполнения.

printf("id = %d remotestep = %d \n", GetLong(Packet->Message, 2), RemoteStep);

вероятно, можно заменить на

std::cout << "id = " << GetLong( Packet->Message, 2 ) << " remotestep = " << RemoteStep << " \n";

  • 1
    Хотя я сам предпочитаю потоки, просто неправда, что вы всегда должны использовать их вместо функций C. printf и др. есть несколько преимуществ по сравнению с потоками C ++: 1.) более удобочитаемым и лаконичным для действительно сложных форматов, 2.) с большей вероятностью быстрее, 3.) проще в использовании для интернационализации и локализации. Однако следует также сказать, что существуют библиотеки, такие как Boost.Format, которые сочетают в себе большинство явных преимуществ.
  • 0
    @ChristianHackl К счастью, я никогда не говорил, что «вы всегда должны использовать их вместо функций C». ;) Кроме того, я согласен с вами по поводу № 1, я скептически отношусь к № 2 и не имею опыта работы с № 3 или Boost.Format (пока).
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню