Thread: shortening this short code? : binary to int casting

  1. #1
    Registered User
    Join Date
    Feb 2009
    Posts
    9

    shortening this short code? : binary to int casting

    I have a 4bytes in a char buffer and I wish to cast to int.
    I'm currently using the code below..

    int *aa = (int*)aBuffer;
    int bb = *aa;

    Can i shorten this code somehow? I seem to have one more int variable than necessary.
    My pointer skills are not too great.

    Something like this..

    int bb = (int)&aBuffer

    ..would be much prettier, but i can guess it does not work.

    Any ideas?
    Last edited by OldGit; 02-24-2009 at 08:02 PM.

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    You'll want to save this (honest)
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
    	char *Int=malloc(4);
    	int X=421500666, *xx=&X;
    	int OldGit; /* this one's for you */
    	Int=(char*)xx;
    	printf("%d\n",*(int*)Int);
    	/* everything good to here...eureka! */
    	OldGit=*(int*)Int; 	/* !!!! */
            OldGit++;
    	printf("%d\n",OldGit);
    	return 0;
    }
    You're gonna love the output too.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    Feb 2009
    Posts
    9
    Quote Originally Posted by MK27 View Post
    You'll want to save this (honest)
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
    	char *Int=malloc(4);
    	int X=421500666, *xx=&X;
    	int OldGit; /* this one's for you */
    	Int=(char*)xx;
    	printf("%d\n",*(int*)Int);
    	/* everything good to here...eureka! */
    	OldGit=*(int*)Int; 	/* !!!! */
            OldGit++;
    	printf("%d\n",OldGit);
    	return 0;
    }
    You're gonna love the output too.
    Crikey! Thanks mk27 (I think) will take some time to decipher that

  4. #4
    Registered User
    Join Date
    Feb 2009
    Posts
    9
    So...

    int aa = *(int*)aBuffer;


    great!

    Cheers
    Last edited by OldGit; 02-24-2009 at 08:31 PM.

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    It's slightly long winded. You don't need *xx at all, you can just say
    Code:
    Int=(char*)&X;
    One thing you can't do is this:
    Code:
    char Int[4];
    which is slightly strange.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    Registered User
    Join Date
    Feb 2009
    Posts
    9
    Quote Originally Posted by MK27 View Post
    It's slightly long winded. You don't need *xx at all, you can just say
    Code:
    Int=(char*)&X;
    I dont quite follow that one, your casting with a char pointer the address of buffer, and storing in an int.

    Now I'm confused. ha. But thankyou, thats solved my predicament.

  7. #7
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by OldGit View Post
    I dont quite follow that one, your casting with a char pointer the address of buffer, and storing in an int.

    Now I'm confused. ha. But thankyou, thats solved my predicament.
    &X would be the address of the location where the int X is stored. Remember *xx=&X? So &X points to X.

    The cast allows Int (a char pointer) to point to X.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Shall I tell you about alignment exceptions and bus errors, or do you want to find that out for yourself first?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Salem View Post
    Shall I tell you about alignment exceptions and bus errors, or do you want to find that out for yourself first?
    Oh please do!
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by MK27 View Post
    Oh please do!
    What Salem is referring to is that some processors (in fact most that are not x86) do not accept memory reads from unaligned addresses, e.g. a 4-byte word must be aligned to a 4-byte block in memory. Bus error is the common message from the processor for "unaligned access", but it is sometimes called other things.


    Some processor & OS combinations use the exception by the processor to fetch the data byte-by-byte into a longer data item (which then takes 10-100 times longer than a single word read), other processors simply cause an error, much like invalid memory address exceptions (page-fault, segmentation violation or whatever you call it).

    So for portable code, copying byte by byte is the correct thing to do.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by matsp View Post
    What Salem is referring to is that some processors (in fact most that are not x86) do not accept memory reads from unaligned addresses, e.g. a 4-byte word must be aligned to a 4-byte block in memory. Bus error is the common message from the processor for "unaligned access", but it is sometimes called other things.
    Ugg. Well, who the $%#^ doesn't use an x86 processor anyway?! I'm not sure how this applies here -- shouldn't char *Int=malloc(4) and int X be aligned properly?

    Some processor & OS combinations use the exception by the processor to fetch the data byte-by-byte into a longer data item (which then takes 10-100 times longer than a single word read), other processors simply cause an error, much like invalid memory address exceptions (page-fault, segmentation violation or whatever you call it).

    So for portable code, copying byte by byte is the correct thing to do.
    So you would bitshift from Int into X?
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
    	char *Int=malloc(4);
    	int X=421500666, i;
    	int OldGit=0; 
    	Int=(char*)&X;
    	printf("%d\n",*(int*)Int);
    	/* everything good to here...eureka! */
    
    	for (i=0; i<4; i++) OldGit+=Int[i]<<i*8;
            
    	printf("%d\n",OldGit);
    	return 0;
    }
    For some reason this does not quite work:
    421500666
    421434874

    ??
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  12. #12
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Try:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
    	unsigned char *Int=malloc(4);
    	int X=421500666, i;
    	int OldGit=0; 
    	Int=(char*)&X;
    	printf("%d\n",*(int*)Int);
    	/* everything good to here...eureka! */
    
    	for (i=0; i<4; i++) OldGit+=Int[i]<<i*8;
            
    	printf("%d\n",OldGit);
    	return 0;
    }
    That should work .

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    The char * is signed, so some parts of the number may be negative - probably not what you want.

    Yes, malloc will be aligned to (at least) the size of double, one would expect (or the size of the allocation, whichever is smaller, and again this is the MINIMUM alignment, it may well be aligned to cache-lines or some other larger boundary).

    But the original post says NOTHING about malloc.



    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by EVOEx View Post
    That should work .
    It does! I am surprised, I would have thought the byte values would be the same either way, since Int is just a pointer to a (signed) int. But I guess one of the middle bytes counted as negative, because of course this works too:
    Code:
     for (i=0; i<4; i++) OldGit+=(unsigned char)Int[i]<<i*8;
    And it works with negative numbers too.

    Still don't quite get this "alignment exceptions and bus errors" scare tho.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by MK27 View Post
    Still don't quite get this "alignment exceptions and bus errors" scare tho.
    Well, if you assume all of the world uses x86, then you can ignore it. If you ever need your code to work on Sparc, Alpha, 68K, 29K, ARM, Mips or some other processor that ISN'T x86, then any code that casts small type pointers (char *, short *, int *) to larger types (e.g. int *, long * or double * ) needs careful consideration or checking that the address is still valid for that type. If it is not (e.g. the data is in an arbitrarily aligned packet of data from a network port) then you need to shuffle bytes.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Debug Error Really Quick Question
    By GCNDoug in forum C Programming
    Replies: 1
    Last Post: 04-23-2007, 12:05 PM
  2. About aes
    By gumit in forum C Programming
    Replies: 13
    Last Post: 10-24-2006, 03:42 PM
  3. Game Won't Compile
    By jothesmo in forum C++ Programming
    Replies: 2
    Last Post: 04-01-2006, 04:24 PM
  4. Need help understanding info in a header file
    By hicpics in forum C Programming
    Replies: 8
    Last Post: 12-02-2005, 12:36 PM
  5. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM