From nobody@FreeBSD.org  Thu Oct 10 18:37:15 2002
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 2C5B537B401
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 10 Oct 2002 18:37:15 -0700 (PDT)
Received: from www.freebsd.org (www.freebsd.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id DB74143EB7
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 10 Oct 2002 18:37:14 -0700 (PDT)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.12.6/8.12.6) with ESMTP id g9B1bE7R017364
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 10 Oct 2002 18:37:14 -0700 (PDT)
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.12.6/8.12.6/Submit) id g9B1bENM017363;
	Thu, 10 Oct 2002 18:37:14 -0700 (PDT)
Message-Id: <200210110137.g9B1bENM017363@www.freebsd.org>
Date: Thu, 10 Oct 2002 18:37:14 -0700 (PDT)
From: Lamont Granquist <lamont@scriptkiddie.org>
To: freebsd-gnats-submit@FreeBSD.org
Subject: kqueues:   EV_SET(kevp++, ...) is non-intuitive
X-Send-Pr-Version: www-1.0

>Number:         43905
>Category:       kern
>Synopsis:       [kqueue] [patch] kqueues: EV_SET(kevp++, ...) is non-intuitive in sys/event.h
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    jmg
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu Oct 10 18:40:02 PDT 2002
>Closed-Date:    
>Last-Modified:  Sun Apr 13 14:40:00 UTC 2014
>Originator:     Lamont Granquist
>Release:        5.0-current Sept 29, 2002
>Organization:
>Environment:
> uname -a
FreeBSD coredump.scriptkiddie.org 5.0-CURRENT FreeBSD 5.0-CURRENT #14: Sun Sep 29 21:38:54 PDT 2002     lamont@coredump.scriptkiddie.org:/usr/obj/usr/src/sys/COREDUMP  i386
  
>Description:
EV_SET() macro call references the first argument 6 times making calls
like EV_SET(kevp++, [...]); not work as-expected and violates principle
of least-surprise.

>How-To-Repeat:
#include <sys/types.h>
#include <sys/event.h>
#include <stdio.h>
#include <stdlib.h>

int main(void) {
        int i;
        struct kevent *kevp = (struct kevent *) malloc(sizeof(struct kevent) * 100);
        for(i = 0; i < 7; i++) {
                printf("%d %p\n", i, kevp + i);
        }
        printf("%p\n", kevp);
        EV_SET(kevp++, 0, EVFILT_READ, EV_ADD, 0, 0, 0);
        printf("%p\n", kevp);
        exit(0);
}


>Fix:
best i can suggest is to convert to an inline function:

static __inline void EV_SET(struct kevent *kevp, const uintptr_t ident, const short filter, const u_short flags, const u_int fflags, const intptr_t data, void * const udata) 
{
        (kevp)->ident = ident;
        (kevp)->filter = filter;
        (kevp)->flags = flags;
        (kevp)->fflags = fflags;
        (kevp)->data = data;
        (kevp)->udata = udata;
}

You could introduce a temporary variable in the EV_SET macro, but things get interesting if there's a namespace collision between that temporary variable and the first argument to EV_SET().

>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->jmg 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Sun Jun 18 05:49:43 UTC 2006 
Responsible-Changed-Why:  
jmg is willing to look at the kqueue PRs. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=43905 

From: Jilles Tjoelker <jilles@stack.nl>
To: bug-followup@FreeBSD.org, lamont@scriptkiddie.org
Cc:  
Subject: Re: kern/43905: [kqueue] [patch] kqueues: EV_SET(kevp++, ...) is
 non-intuitive in sys/event.h
Date: Sun, 13 Apr 2014 16:33:09 +0200

 In FreeBSD PR kern/43905, you wrote:
 > EV_SET() macro call references the first argument 6 times making calls
 > like EV_SET(kevp++, [...]); not work as-expected and violates
 > principle of least-surprise.
 
 SVN r110241, Sun Feb 2 2003, fixed this using a temporary variable, but
 this may cause problems if an identifier 'kevp' is in scope.
 
 As an alternative to the inline function, C99 compound literals and
 designated initializers allow doing this cleanly using a macro:
 
 Index: sys/sys/event.h
 ===================================================================
 --- sys/sys/event.h	(revision 264352)
 +++ sys/sys/event.h	(working copy)
 @@ -45,14 +45,15 @@
  #define EVFILT_SENDFILE		(-12)	/* attached to sendfile requests */
  #define EVFILT_SYSCOUNT		12
  
 -#define EV_SET(kevp_, a, b, c, d, e, f) do {	\
 -	struct kevent *kevp = (kevp_);		\
 -	(kevp)->ident = (a);			\
 -	(kevp)->filter = (b);			\
 -	(kevp)->flags = (c);			\
 -	(kevp)->fflags = (d);			\
 -	(kevp)->data = (e);			\
 -	(kevp)->udata = (f);			\
 +#define EV_SET(kevp, a, b, c, d, e, f) do {	\
 +	*(kevp) = (struct kevent){		\
 +		.ident = (a),			\
 +		.filter = (b),			\
 +		.flags = (c),			\
 +		.fflags = (d),			\
 +		.data = (e),			\
 +		.udata = (f)			\
 +	};					\
  } while(0)
  
  struct kevent {
 
 -- 
 Jilles Tjoelker
>Unformatted:
