[FFmpeg-devel] [PATCH 3/7] Add alias-safe union typedefs

Michael Niedermayer michaelni
Sun Jan 31 14:37:17 CET 2010


On Sun, Jan 31, 2010 at 02:08:15PM +0100, Michael Niedermayer wrote:
> On Fri, Jan 29, 2010 at 11:06:15AM +0000, M?ns Rullg?rd wrote:
> > Michael Niedermayer <michaelni at gmx.at> writes:
> > 
> > > On Fri, Jan 29, 2010 at 02:12:10AM +0000, Mans Rullgard wrote:
> > >> ---
> > >>  libavutil/intreadwrite.h |   18 ++++++++++++++++++
> > >>  1 files changed, 18 insertions(+), 0 deletions(-)
> > >
> > > I belive these types would be usefull to projects using libavutil
> > 
> > Here we go again...
> > 
> > Those rely on the may_alias attribute being supported, which is tested
> > by configure.  I guess it could be changed to check for gcc version
> > instead, although that is less reliable with non-gcc compilers.
> 
> After looking in the c spec ..
> why do we need may_alias at all? a union should be enough or am i missing
> something?
> 
> That said, these unions only need a char array as a char access can alias
> anything. Otherwise if iam wrong they need float & double too
> 
> And with gcc a much better solution is along the lines of
> 
> #define UD(v,access)\
>     ((union {\
>         access a;\
>         typeof(v) b[sizeof(access)/sizeof(typeof(v))];\
>     }*)(v))->a
> 
> this specifies only the effective type + the accesed type and thus reduces
> the restrictions placed on the optimizer.
> It also shows how ridiculous this is as the compiler clearly knows the types
> already.

Here are the 2 macros one for gcc like compilers and one for ISO C

#define AV_UA(v,access)\
    ((union {\
        access a;\
        typeof(v) b[sizeof(access)/sizeof(typeof(v))];\
    }*)(v))->a

#define AV_UA2(v,access)\
    ((union {\
        access a;\
        char b[sizeof(access)];\
    }*)(v))->a

but now the bad news, none works, not even the attribue may_alias code
unless iam missing something ...
(tested with gcc 4.3 and 4.4)

as demonstration:

#include <stdio.h>
#include <stdlib.h>

typedef union u1{
    int i;
    char c[4];
}u1;

typedef union u2 {
    int i;
    short s[2];
}u2;

typedef union __attribute__((__may_alias__)) u3 {
    int i;
    short s[2];
    char c[4];
}u3;

#define AV_UA(v,access)\
    ((union {\
        access a;\
        typeof(v) b[sizeof(access)/sizeof(typeof(v))];\
    }*)(v))->a

#define AV_UA2(v,access)\
    ((union {\
        access a;\
        char b[sizeof(access)];\
    }*)(v))->a

#define AV_UA3(v,access)\
    ((union{\
        access a;\
        char b[sizeof(access)];\
    }*)(v))->a
int main(){
    short test[4]={1,2,3,4};
    int a,b,c,d,e,f,g;
    test[0]=2;
    a= *(int*)test;
    test[0]=3;
    b=((u1*)test)->i;
    test[0]=4;
    c=((u2*)test)->i;
    test[0]=5;
    d=((u3*)test)->i;
    test[0]=6;
    e=AV_UA(test,int);
    test[0]=7;
    f=AV_UA2(test,int);
    test[0]=8;
    g=AV_UA3(test,int);
    test[0]=9;

    printf("%X %X %X %X %X %X %X\n", a,b,c,d,e,f,g);
    return 1;
}

ouput with -O3 is
8048429 8048429 8048429 8048429 8048429 8048429 8048429
with -O3 -fno-strict-aliasing
20002 20003 20004 20005 20006 20007 20008


[...]

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Everything should be made as simple as possible, but not simpler.
-- Albert Einstein
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20100131/b208f158/attachment.pgp>



More information about the ffmpeg-devel mailing list