Thread: Function return a value

  1. #1
    Registered User
    Join Date
    Jul 2008
    Posts
    7

    Question Function return a value

    I am an old assembly programmer and I am trying to teach myself c programming.

    I have a function that converts a 32 bit value for endianess and I can't figure out why I do not the the corrected value returned.

    This is part of my code

    Code:
    int process_cmd(int sock)
    {
            int cmd, ccmd, res;
            int (* process_func)(int);
    
            RECV_INTEGER(&cmd);
            ccmd=cmd;
            BYTESWAP2(ccmd);
            printf("converted %08X\n", ccmd);
    This is my function

    Code:
    int BYTESWAP2(ccmd)
    {
          return (((ccmd&0x000000FF)<<24)+((ccmd&0x0000FF00)<<8)+
                 ((ccmd&0x00FF0000)>>8)+((ccmd&0xFF000000)>>24));
    }
    The function input is 0158DA00 and should return 00DA5801 and yet it
    after the function ccmd = 0158DA00

    What am I doing wrong ?

  2. #2
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    You have two of your masks incorrect, this one ((ccmd&0x000000FF)<<24) and ((ccmd&0xFF000000)>>24). And for maximum portability, the input to BYTESWAP should be an unsigned int:
    Code:
    int BYTESWAP2(unsigned ccmd)
    EDIT: My bad, the masks are correct.
    Last edited by swoopy; 07-16-2008 at 07:11 PM.

  3. #3
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    And you never assigned the return value to anything:
    Code:
            var = BYTESWAP2(ccmd);
    Or you could simply print out the value of BYTESWAP2(ccmd).

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    The following code, which should look familiar:
    Code:
    #include <stdio.h>
    
    int BYTESWAP2(int ccmd)
    {
          return (((ccmd&0x000000FF)<<24)+((ccmd&0x0000FF00)<<8)+
                 ((ccmd&0x00FF0000)>>8)+((ccmd&0xFF000000)>>24));
    }
    
    int main(void) {
    
        int foo = 0x0158DA00;
        int bar;
        bar = BYTESWAP2(foo);
        printf("&#37;x %x\n", foo, bar);
        return 0;
    }
    gives the output
    Code:
    158da00 da5801
    as expected. Consequently, any errors you have are elsewhere. (Edit: specifically, as swoopy noted, in your lack of doing anything with the answer returned.)

    Based solely on names, I'm guessing you're trying to use the functions htonl and ntohl anyway, so why not do so?

  5. #5
    Registered User
    Join Date
    Jul 2008
    Posts
    7
    I understand I did not do the unsigned.

    but my math is correct.

    I changed my function to

    Code:
    int BYTESWAP2(ccmd)
    {
          ccmd =  (((ccmd&0x000000FF)<<24)+((ccmd&0x0000FF00)<<8)+
                       ((ccmd&0x00FF0000)>>8)+((ccmd&0xFF000000)>>24));
                       printf("finnish %08x\n", ccmd);
                       return (ccmd);
    }
    and it prints the correct value

    input 0158DA00 and the printed result is 00DA5801

    just in either case I get the input value not the result

  6. #6
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >and it prints the correct value
    Just be sure you assign the result to something back in process_cmd().

  7. #7
    Registered User
    Join Date
    Jul 2008
    Posts
    7
    I did not use the ntohl or htonl because I have to choose which one. This works both ways with the same routine

  8. #8
    Registered User
    Join Date
    Jul 2008
    Posts
    7
    Ok I see why I am not getting the result

    Thank you

  9. #9
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >I did not use the ntohl or htonl because I have to choose which one. This works both ways with the same routine
    As long as you don't sometime in the future run your code on a different platform, that's ok.

  10. #10
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by gr8npwrfl View Post
    I did not use the ntohl or htonl because I have to choose which one. This works both ways with the same routine
    I'm pretty sure ntohl() and htonl() do exactly the same thing. There's no way for the function to know what endiness the number is already in, it just flips the bytes around and assumes you knew what the original endiness was...

  11. #11
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Quote Originally Posted by cpjust View Post
    I'm pretty sure ntohl() and htonl() do exactly the same thing. There's no way for the function to know what endiness the number is already in, it just flips the bytes around and assumes you knew what the original endiness was...
    I'd be very surprised if that's the case.

  12. #12
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by cpjust View Post
    I'm pretty sure ntohl() and htonl() do exactly the same thing. There's no way for the function to know what endiness the number is already in, it just flips the bytes around and assumes you knew what the original endiness was...
    Well, hopefully the library knows what the host-order is; and network order is well defined. So the function "knows" either to flip (as above), or do nothing....

  13. #13
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by tabstop View Post
    Well, hopefully the library knows what the host-order is; and network order is well defined. So the function "knows" either to flip (as above), or do nothing....
    How can it possibly know the difference between Big Endian and Little Endian? Just by looking at a number there's no way to know.
    Is 0xFE1265CD02 Big Endian or Little Endian? There's no special bit (like a signed number) that says this is Big Endian...
    Code:
    #include <iostream>
    #include <winsock2.h>
    
    using namespace std;
    
    int main()
    {
    	unsigned long num = 1234567890;
    	cout << num << endl;
    	num = htonl( num );
    	cout << num << endl;
    	num = htonl( num );
    	cout << num << endl;
    	return 0;
    }
    Output:
    Code:
    1234567890
    3523384905
    1234567890
    Last edited by cpjust; 07-16-2008 at 09:34 PM.

  14. #14
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by cpjust View Post
    How can it possibly know the difference between Big Endian and Little Endian? Just by looking at a number there's no way to know.
    Is 0xFE1265CD02 Big Endian or Little Endian? There's no special bit (like a signed number) that says this is Big Endian...
    It knows the difference, because it knows the machine. If the machine is a little-endian machine, the number is little-endian. If the machine is big-endian, the number is big-endian.

  15. #15
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by tabstop View Post
    It knows the difference, because it knows the machine. If the machine is a little-endian machine, the number is little-endian. If the machine is big-endian, the number is big-endian.
    Yes, but on a Little Endian machine, both ntohl() and htonl() swap bytes around. On a Big Endian machine, both ntohl() and htonl() do nothing.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. doubt in c parser coding
    By akshara.sinha in forum C Programming
    Replies: 4
    Last Post: 12-23-2007, 01:49 PM
  2. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  3. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  4. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  5. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM