Hi all.

> commit 2436ffa9b44911cee7646a197c0eea1e5743c591
> 
>     Use (uint8_t *) for buf_(set|get)_u(32|64) instead of (void *)

I don't believe that typecasts are evil, but ... at times, they can silently 
hide terrible bugs.

In order to reduce typecasts in my own code, I replace things like this...

struct MyStructure
{
        uint8_t                 *address;
        uint32_t                length;
};

buffer.length = 22;
buffer.address = (uint8_t *)malloc(buffer.length);
(uint16_t *)buffer.address++ = value;

... by this ...

struct MyStructure
{
        union {
                void            *address;               /* used only with 
malloc/free */
                uint8_t         *address8;              /* byte access */
                uint16_t        *address16;             /* 16-bit word access */
                uint32_t        *address32;             /* 32-bit word access */
        };                                                              /* this 
union is nameless, so it's transparent */
        uint32_t                length;
};

buffer.length = 22;
buffer.address = malloc(buffer.length);
*buffer.address16++ = value;

... Of course, this technique cannot be applied in all circumstances, and it 
should not be used for sharing pointers with integers.
But upcasting and downcasting type sizes (eg. between uint8_t and uint32_t) 
does not brin any warnings either (though you'll have to know what you're doing 
and always make sure your pointer is aligned to a 32-bit boundary).

I believe my 'technique' has a copule of advantages over type-casting...
1: It makes the code 'cleaner' and neater to look at.
2: It limits the possible types you can 'cast' to.
Any disadvantages ? -Yes.
1: You can't directly see that address has the same value as address32.
2: Incrementing address32 could perhaps be mistaken by people who are not 
familiar with this style; there's a difference between incrementing address8 
and address32.

...But in general, I find it safer myself and also find that it makes the code 
more tidy.

Note: It's also possible to do this to local variables - eg. registers - via 
for instance a #define, but I've not found the need for that myself yet.
Example:
#define MULTIPTR(a) union{ void *a; uint8_t *a ## 8; uint16_t a ## 16; uint32_t 
a ## 32; uint64_t a ## 64; }
        MULTIPTR(p);


Love
Jens

------------------------------------------------------------------------------
New Year. New Location. New Benefits. New Data Center in Ashburn, VA.
GigeNET is offering a free month of service with a new server in Ashburn.
Choose from 2 high performing configs, both with 100TB of bandwidth.
Higher redundancy.Lower latency.Increased capacity.Completely compliant.
http://p.sf.net/sfu/gigenet
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to