On Fri, 08 Jul 2011 09:54:40 -0400, Steven Schveighoffer wrote: > On Thu, 07 Jul 2011 16:23:33 -0400, teo <teo.ubu...@yahoo.com> wrote: > >> On Thu, 07 Jul 2011 11:57:51 -0400, Steven Schveighoffer wrote: >> >>> Well, I can't really say I understand the point of using this macro at >>> all. sizeof is a builtin, and part of the C spec. Why not just use >>> sizeof? >>> >>> >> Well, have a look please at ioctl.h (linux). You will find the >> following macros: >> >> >> #define _IOC(dir,type,nr,size) \ >> (((dir) << _IOC_DIRSHIFT) | \ >> ((type) << _IOC_TYPESHIFT) | \ >> ((nr) << _IOC_NRSHIFT) | \ >> ((size) << _IOC_SIZESHIFT)) >> >> #define _IOC_TYPECHECK(t) (sizeof(t)) >> >> /* used to create numbers */ >> #define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) #define >> _IOR(type,nr,size) >> _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK (size))) >> #define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr), >> (_IOC_TYPECHECK(size))) >> #define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr), >> (_IOC_TYPECHECK(size))) >> >> >> This is what I am after. However I thought that a simplified case will >> make it easier to describe the problem. >> >> > Hm... I once wrote a D module that accessed a linux device driver (ipmi > driver to be specific). I did it in D1, and I used CTFE. For sure, > t.sizeof should work instead of _IOC_TYPECHECK. But Linux supports a > multitude of CPUs, perhaps other CPUs need a different macro for this. > It's the only thing I can think of to explain having a specific macro to > do sizeof. > > -Steve
Steve, I translated those macros to regular functions and it works that way (using T.sizeof), however I could have used a function template instead as you suggested before and therefore I have a question: Are there any benefits of using function templates instead of regular functions in that particular case? The above leads me to another question: are those functions evaluated at compile-time? I suppose they are not. Here an example usage: uint _IOC(uint dir, uint type, uint nr, uint size) { return (dir << _IOC_DIRSHIFT) | (type << _IOC_TYPESHIFT) | (nr << _IOC_NRSHIFT) | (size << _IOC_SIZESHIFT); } uint _IO(uint type, uint nr) { return _IOC(_IOC_NONE, type, nr, 0); } uint _IOWR(uint type, uint nr, uint size) { return _IOC(_IOC_READ | _IOC_WRITE, type, nr, size); } In another module define the constants: const C1 = _IO(1, 2); const C2 = _IOWR(2, 3, A.sizeof);