tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Our dirfd(3) is a macro not a function



stix%stix.id.au@localhost said:
  |  POSIX appears to require a function but allow an additional macro.

Everything defined as a function in POSIX is required to be implemented
as a function (so, amongst other things, it can be passed by reference
to another function, or accessed via a pointer).

So if we're not providing dirfd() as a function, we should be.  It wouldn't
exactly be hard...

Everything that is defined as a function is allowed to also be implemented
as a macro, and applications that desire to access them other ways than
simply using them have to take steps to make that happen.  Whether the C++
usage described here counts for that I have no idea, but possibly not, as
as I recall it (cannot locate the original msg at the minute), while there
was syntax preceding the "dirfd" that word was followed by a '(' which would
trigger the macro expansion, unless there was a #undef dirfd in scope (after
#include of <dirent.h>) to remove the macro.   If there was no such thing,
it is likely that there's also a bug in boost, as dirfd() is a POSIX specified
function, so it is permitted to appear as a macro.

What POSIX actually says about this is (from XSH 2.1.1) is

  2. Any function declared in a header may also be implemented as a macro
     defined in the header, so a function should not be declared explicitly
     if its header is included. Any macro definition of a function can be
     suppressed locally by enclosing the name of the function in parentheses,
     because the name is then not followed by the <left-parenthesis> that
     indicates expansion of a macro function name. For the same syntactic
     reason, it is permitted to take the address of a function even if it is
     also defined as a macro. The use of the C-language #undef construct to
     remove any such macro definition shall also ensure that an actual
     function is referred to.

  3. Any invocation of a function that is implemented as a macro shall
     expand to code that evaluates each of its arguments exactly once,
     fully protected by parentheses where necessary, so it is generally
     safe to use arbitrary expressions as arguments.

While not relevant to dirfd() note than in (3) there, "exactly once" is
not "at most once" - each arg must be evaluated (just as it would be if
being used as an arg to a function call).

kre



Home | Main Index | Thread Index | Old Index