Он никогда не появляется в статусе 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);
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*
.
%ld
: P хаха та же ошибка
Вы можете изменить свои утверждения для использования 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";
printf
и др. есть несколько преимуществ по сравнению с потоками C ++: 1.) более удобочитаемым и лаконичным для действительно сложных форматов, 2.) с большей вероятностью быстрее, 3.) проще в использовании для интернационализации и локализации. Однако следует также сказать, что существуют библиотеки, такие как Boost.Format, которые сочетают в себе большинство явных преимуществ.
-Wall -Wextra
).long
строки с использованием%d
имеет неопределенное поведение, хотя это может и не быть причиной проблемы.