Question

It never goes in the if statment when obviously 0 == 0 the sizeof() of both the function return long and regular long both say 8, I don't know what else could be wrong here.

Declarations:

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]);
}

Debug code:

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");
            ...
        }

Output information:

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

I compiled this under compat-gcc-34-c++ aka g++34, I can't use newer g++ compilers as they give too much warnings and even errors.

with -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)

line 1880 is one of the

printf("id = %l  remotestep = %l \n", GetLong(Packet->Message, 2), RemoteStep);
Was it helpful?

Solution

The long type should not be printed with %d, this is explicitly undefined in the specification. For example,

Each conversion specification is introduced by the '%' character ...
...
If a conversion specification does not match one of the above forms, the behavior is undefined. If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined. http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html

(the documentation applies to printf as well as fprintf)


Thus you cannot rely on the output of,

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

to determine that

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

is in fact incorrect, and you will need to fix your debug statements first:

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

In your case it is also preferable to use memcpy instead of the pointer cast,

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

since long* can have a stricter alignment requirement on your platform than a char*.

OTHER TIPS

You could change your statements to use std::cout instead of printf, since you tagged the question with C++ and not with C. With cout you will not get these surprising effects of %d or other % specifiers during runtime.

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

can probably be replaced by

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top