Thread: *(DWORD*)&dwTemp

  1. #1
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195

    *(DWORD*)&dwTemp

    just a thought, but will

    Code:
    void Foo(BYTE* pTemp){
       DWORD dwNew;
       dwNew = *(DWORD*)&pTemp[4];
       return dwNew;
       }
    properly return the value in pTemp[x] ? I know its convoluted, but I actualyl have a situation where this particular redirect would make the code simpler lol.

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by abachler View Post
    properly return the value in pTemp[x] ? I know its convoluted, but I actualyl have a situation where this particular redirect would make the code simpler lol.
    No, since pTemp[x] is a BYTE and you are extracting a DWORD.. This may actually crash on some systems with tighter alignment requirements. There is no guarantee that the BYTE * is aligned to a DWORD boundary, so casting it to a DWORD pointer and dereferencing it could cause a bus error.

  3. #3
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Indeed, such a thing would cause problems back when I used to program on 680x0 Macs.
    Even if it doesn't cause a crash on the hardware you are using, unaligned reads tend to be slower anyway.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  4. #4
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Foo() returns void, so you can't return anything.
    It should give you a compiler error or warning shouldn't it?

  5. #5
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    Alignment isnt an issue and I dont care about the function, just the recast.
    Last edited by abachler; 04-09-2008 at 02:36 PM.

  6. #6
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    the value will consist of pTemp[4] pTemp[5] pTemp[6] pTemp[7] - not only pTemp[x]

    and you will have endian problems here

    why not to use binary shift and Or operations to reconstract DWORd value from 4 BYTE values?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  7. #7
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    So the answer is yes, it will work. You were assuming I want only the byte value 0-255, when in fact I want all 4 bytes, I only use BYTE* so that I get a pointer resolution of 1.

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You take the address of a byte and cast that into a pointer to a DWORD (32-bit unsigned integer), which is technically it is undefined, but in a x86 system, it's fair to assume that it will work just fine [1], since x86 is capable of reading any value from any alignment (pedantically: as long as you don't cross the limit of a segment, which is unlikely in for example Windows or Linux).

    Other systems may fail due to alignment. If you can guarantee that the alignment is correct (e.g. the data comes from a buffer that you have allocated, and you have checked/aligned it correctly in the first place), then it should be OK in other architectures too (as long as a pointer to byte and a pointer to DWORD are compatible enough that the compiler can at all convert those - which I think is the case on 99.9% of architectures, but I'm just making sure I've covered the bases).

    [1] There is a bit in the x86 32/64-bitprocessors (486 and higher) that can be used to trap unaligned accesses (in user mode). I've yet to see any OS that enables this bit, but technically, it can be done... In which case, the undefined behavious is definitely possible in such a system, since the behaviour of the unaligned access fault handler is not defined by the C standard, and it could for example stop your application.

    --
    Mats
    Last edited by matsp; 04-09-2008 at 03:29 PM.
    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.

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    I've yet to see any OS that enables this bit
    I've seen something similar done (but on an Alpha architecture) in an assembly programming assignment just to make sure all our accesses are aligned - if the trap handler fired, you got no points.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  10. #10
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    Nice mountain you made out of that molehill. As I stated, alignment is not an issue, so please stop hijacking the thread to discuss alignment, thanks.

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    They already told you the answer and stated it might cause problems. What more do you wish to know? The best way to return a DWORD is to cast it DWORD and return it. Otherwise, if you need to return a DWORD pointer, you need to make a temporary allocation or use a buffer to fill with the value of one byte cast to DWORD.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    They already told you the answer and stated it might cause problems. What more do you wish to know? The best way to return a DWORD is to cast it DWORD and return it. Otherwise, if you need to return a DWORD pointer, you need to make a temporary allocation or use a buffer to fill with the value of one byte cast to DWORD.
    If you want to extract a DWORD out of an array of BYTE, then you need to take the address and cast it to pointer to DWORD, then dereference that pointer. Otherwise, we'll be converting a BYTE to DWORD by filling then other 3 bytes with zero, which I doubt is what abachler actually wanted.

    --
    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.

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I think I just cover both methods there.
    Or maybe I forgot one.

    Returning just a DWORD:
    Code:
    DWORD Foo(BYTE* pTemp){
        DWORD dwNew;
        dwNew = (DWORD)pTemp[4];
        return dwNew;
    }
    And returning a DWORD pointer:
    Code:
    DWORD Foo(BYTE* pTemp, DWORD& dwBuffer){
        memcpy(&dwBuffer, &pTemp[4], sizeof(DWORD));
    }
    (Not tested)

    I think this should avoid unaligned issues.
    Unless memcpy works in ways I don't know or the initial source pointer must be aligned, but I don't think it needs to? It's up to the C implementation.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, if you want it portable, memcpy() or manually copying bytes [likely to be better than memcpy if the compiler doesn't inline memcpy - most good compilers do inline it, at least for constant (small) size operations].

    You can of course also copy into and return a temporary DWORD value, like this:
    Code:
    DWORD foo(BYTE *ptr)
    {
       DWORD dw;
       memcpy(&dw, &ptr[4], sizeof(DWORD);
       return dw;
    }
    The first example does not work. It is guaranteed to give you a value of 0..255, since it just casts the element 4 of the byte array to DWORD. You need the malarky of taking an address and dereferencing it.

    --
    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.

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Well, I did mention it was another way of doing it. There was not mention as to which method was the one that was needed.
    So anyway, that's about how it works.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed