This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Hard fault at misaligned memcpy memset

we made some simple tests with STM32F100 Value Line Eval Board:

//------------------------------------------------------------------------------
// Variables
static unsigned char sDstBuf[1024]; // 1KiB
static unsigned char sSrcBuf[sizeof(sDstBuf)];

printf("Copying words from misaligned src to aligned dst buffer... ");
memset(sDstBuf, 0xcd, sizeof(sDstBuf));

with optimize Level 3, optimize for time this takes
120usec

with optimize Level 0
155usec

almost the same if memcpy is used:
memcpy(sDstBuf, (const void *)0xcd, sizeof(sDstBuf));

It runs into hard fault, if optimize Level >=1 and optimise for time is not set.

I think this is a compiler error..

We ran into this before with MDK 4.60, now we use 4.70A

Werner

Parents
  • To clarify what I meant about (int *), consider:

    char a[10];
    char *cp = &a[1];
    void *vp = &a[1];
    int *ip1, *ip2;
    ...
        ip1 = (int *)cp;  // may be undefined behavior
        ip2 = cp;    // C++ requires a cast here, C does not; still may be undefined behavior
    ...
    

    The two statements both invoke undefined behavior if '&a[1]' does not have the alignment required for 'int' (and it probably doesn't). Probably, nothing bad will happen until '*ip1' or '*ip2' is used. Of course, it might also be the case that nothing bad happens right away or ever -- there are no requirements at all on what happens after undefined behavior.

    In my opinion, casts (and converting from 'void *') are something to be avoided when at all possible because they can easily hide errors. There are cases where they are necessary, but I prefer to avoid using them.

    [In my weak attempt at lawyer-style humor in a post above, I, of course, meant "..., up to and including, but not limited to, ...".]

Reply
  • To clarify what I meant about (int *), consider:

    char a[10];
    char *cp = &a[1];
    void *vp = &a[1];
    int *ip1, *ip2;
    ...
        ip1 = (int *)cp;  // may be undefined behavior
        ip2 = cp;    // C++ requires a cast here, C does not; still may be undefined behavior
    ...
    

    The two statements both invoke undefined behavior if '&a[1]' does not have the alignment required for 'int' (and it probably doesn't). Probably, nothing bad will happen until '*ip1' or '*ip2' is used. Of course, it might also be the case that nothing bad happens right away or ever -- there are no requirements at all on what happens after undefined behavior.

    In my opinion, casts (and converting from 'void *') are something to be avoided when at all possible because they can easily hide errors. There are cases where they are necessary, but I prefer to avoid using them.

    [In my weak attempt at lawyer-style humor in a post above, I, of course, meant "..., up to and including, but not limited to, ...".]

Children
  • You could consider using a __packed pointer.

    Understand the underlying hardware along with what the processor does would help you make a sensible decision about what is best.

    My advice would be to not just take the typical "you are wrong" and "the best way to do it is to" and the frequent "the only way to do it is to" that frequently appears from beginners right through to experts and professionals. Just remember that there is more than one way to skin a cat.

    If you listen carefully, you might just be able to hear the cries of outrage.

  • Instead of using packed pointers, the code should do the best to align the data manually if trying to store big objects in arrays of smaller objects.