On Mon, Nov 14, 2011, Steffen Daode Nurpmeso wrote:
> Hi,
> 
> my dhclient.c patch was very wrong.
> And it (falsely) removed a runtime check of some struct member
> size.  But this very hunk (while wrong) led me to a question.
> Since saving even some bytes in shell scripts counts so much,
> i wonder why compile-time assertions are not used at all (AFAIK).
> I.e., the simple change in that POC patch below saves 76 bytes on
> a i386.  (And that is only on-disk.)
> 
> Is there a reason not to use CTASSERT (and some kind of
> member_sizeof())?  I couldn't find just any discussion on that in
> marc and gmane.

Seems like a good idea, but your patch is wrong.  Off by one because
strlen != sizeof.

> 
> --steffen
> 
> Index: sys/sys/cdefs.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/cdefs.h,v
> retrieving revision 1.31
> diff -a -p -u -r1.31 cdefs.h
> --- sys/sys/cdefs.h   1 Oct 2010 04:51:49 -0000       1.31
> +++ sys/sys/cdefs.h   14 Nov 2011 17:21:49 -0000
> @@ -86,6 +86,18 @@
> #define       __CONCAT(x,y)   x/**/y
> #define       __STRING(x)     "x"
> 
> +/*
> + * Compile time assertion
> + */
> +#define __CTASSERT(X)                __CTASSERT1((X), __LINE__)
> +#define __CTASSERT1(X,L)     __CTASSERT2((X), L)
> +#define __CTASSERT2(X,L)     typedef char __CTASSERT_bail_ ## L[(X) ? 1 : -1]
> +
> +/*
> + * __member_sizeof(T,M) - 0x8 to avoid cc warnings and too aggr.
> optimization
> + */
> +#define __member_sizeof(T,M) sizeof(((T *)0x8)->M)
> +
> #if !defined(__GNUC__) && !defined(lint)
> #define       __const                         /* delete pseudo-ANSI C 
> keywords */
> #define       __inline
> Index: sbin/dhclient/dhcpd.h
> ===================================================================
> RCS file: /cvs/src/sbin/dhclient/dhcpd.h,v
> retrieving revision 1.73
> diff -a -p -u -r1.73 dhcpd.h
> --- sbin/dhclient/dhcpd.h     11 May 2011 14:38:36 -0000      1.73
> +++ sbin/dhclient/dhcpd.h     14 Nov 2011 17:21:49 -0000
> @@ -189,6 +189,8 @@ struct interface_info {
> int                    rdomain;
> };
> 
> +__CTASSERT(__member_sizeof(struct interface_info, name) >= IFNAMSIZ);
> +
> struct timeout {
> struct timeout        *next;
> time_t                 when;
> Index: sbin/dhclient/dhclient.c
> ===================================================================
> RCS file: /cvs/src/sbin/dhclient/dhclient.c,v
> retrieving revision 1.141
> diff -a -p -u -r1.141 dhclient.c
> --- sbin/dhclient/dhclient.c  11 May 2011 14:38:36 -0000      1.141
> +++ sbin/dhclient/dhclient.c  14 Nov 2011 17:21:49 -0000
> @@ -2103,8 +2103,7 @@ get_ifname(char *ifname, char *arg)
> arg = ifg->ifgrq_member;
> }
> 
> -             if (strlcpy(ifi->name, arg, IFNAMSIZ) >= IFNAMSIZ)
> -                     error("Interface name too long: %m");
> +             (void)strlcpy(ifi->name, arg, IFNAMSIZ);
> 
> free(ifgr.ifgr_groups);
> close(s);

Reply via email to