long在C ++中不等于另一个long

时间:2014-04-06 12:17:16

标签: c++ long-integer

如果显然0 == 0函数返回long和常规long的sizeof()都显示为8,那么它永远不会出现在if语句中。我不知道这里还有什么错误。

声明:

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

我在compat-gcc-34-c++又名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);

2 个答案:

答案 0 :(得分: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而不是指针强制转换,

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

因为long*可以在您的平台上具有比char*更严格的对齐要求。

答案 1 :(得分:0)

您可以将语句更改为使用std :: cout而不是printf,因为您使用C ++而不是使用C标记了问题。使用cout,您将无法在运行时获得%d或其他%说明符的这些令人惊讶的效果。 / p>

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

可能会被

取代

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