Date: Thu, 26 Mar 2015 02:24:22 +1100 (EST) From: Bruce Evans <brde@optusnet.com.au> To: Hans Petter Selasky <hps@selasky.org> Cc: Emeric POUPON <emeric.poupon@stormshield.eu>, freebsd-net <freebsd-net@freebsd.org>, Adrian Chadd <adrian@freebsd.org> Subject: Re: Fragment questions Message-ID: <20150326005055.C3948@besplex.bde.org> In-Reply-To: <5512BB1A.9070900@selasky.org> References: <522774578.25519037.1426765109046.JavaMail.zimbra@stormshield.eu> <550AC709.1050404@selasky.org> <2047974073.25663527.1426858267777.JavaMail.zimbra@stormshield.eu> <550C5FC6.6020401@selasky.org> <CAJ-Vmo=LkFc4sqbBSVeLE=7adV1nCuRDUO4ECUv8r6EYp=Oezw@mail.gmail.com> <550C6D65.6070409@selasky.org> <CAJ-Vmo=a6nzfRFH1cu0VefGk1opJf4WAt6u7ugT0uRMbjWvA-A@mail.gmail.com> <1776547746.25937476.1427189208729.JavaMail.zimbra@stormshield.eu> <5512BB1A.9070900@selasky.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 25 Mar 2015, Hans Petter Selasky wrote: > On 03/24/15 10:26, Emeric POUPON wrote: >> >> Please find attached a proposal using atomic_fetchadd. > ... > I think however we should define the code like a function, because the > htons() might be a macro, referring the input argument multiple times ... htons() might be a macro, but then it must act like a function. See POSIX 2.1.1 "Use and Implementation of Functions" clauses 2-3. In particular, it must not evaluate its args more than once (clause 3). These clauses copy the not so good wording of the C standard. E.g., clause 3 also requires parenthesization of the args, but much more than 2.1.1 specifies is required to replace a function by a macro. Args must also be converted the same as a prototype would. Casts to do the conversions are not good enough, since casts should suppress warnings for dubious conversions (e.g., htons(x) where x is a pointer) while the more automatic conversions done by prototypes should warn. 2.1.1 cannot say that the macro implementation behaves identically, since it the behaviour is slightly different. It doesn't mention types at all. The closest it comes to requiring similar behaviour is just "Any function declared in a header may also be implemented as a macro defined in the header". But this is impossible to implement a function as a macro precisely, and 2.1.1 isn't very clear about which parts must be precise (it mentions some parts that are imprecise). POSIX's section about htons() (and most functions) is unclear about this. It says that "On some implementations, these functions [htons family] are _defined_ as macros. That is almost useless, since any function may _also_ be _implemented_ as a macro. It is unclear if the possibility of being defined as a macro means that the function version might not exist. Actually, this is clear in the functions' header. For most functions, e.g., exit(), the wording is that "The following functions shall be _declared_ as functions and may also be defined as macros". [Here it is unclear if _declared_ means more than the declaration of a prototype.] For the htons() family, the wording for netinet/in.h is "The following shall either be declared as functions, defined as macros, or both". FreeBSD's htons() is careful about this. The x86 version uses inline functions to avoid multiple evaluation at the type level. This also accidentally gives the right level of warnings. FreeBSD's man page gives no hints about this except the lower case name of the APIs conventionally means that they are not unsafe macros. It describes the htons() family as "These routines". Routines are unusual in C and in man pages. (In /usr/share/man/man3, there are about 80000 lines matching "function" and only 10000 matching "routine", with mist of the latter in contribish places (lots in spam N-tuplicates from libc/rpc.) Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20150326005055.C3948>