tech-userlevel archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: EV_SET() better C++ compat with alternative implementations
On Sun, Aug 11, 2019 at 03:57:50 +0200, Kamil Rytarowski wrote:
> On 11.08.2019 02:56, Valery Ushakov wrote:
> > Kamil Rytarowski <n54%gmx.com@localhost> wrote:
> >
> >> Cast of udata from void* to intptr_t shall be done with
> >> reinterpret_cast<> otherwise a C++ compiler errors.
> >>
> >> Defining __REINTERPRET_CAST [1] and using it, did not work as a compiler
> >> protested for NULL argument "warning: passing NULL to non-pointer argument".
> >>
> >> Using double cast __REINTERPRET_CAST(intptr_t, __CAST(void *, (udata)))
> >> pacified the warning/error about passing NULL in C++, but it created the
> >> problem of calling EV_SET using the native argument type intptr_t.
> >
> > You are reporting quite an abstract summary that is not so easy to
> > follow for someone who hasn't done all the same experiments that you
> > already have done.
>
>
> $ cat /tmp/test.cpp
>
>
> #include <sys/types.h>
> #include <sys/event.h>
>
> int
> main(int argc, char **argv)
> {
> struct kevent kv;
>
> EV_SET(&kv, 0, 0, 0, 0, 0, 0);
> EV_SET(&kv, 0, 0, 0, 0, 0, NULL);
> EV_SET(&kv, 0, 0, 0, 0, 0, nullptr);
> EV_SET(&kv, 0, 0, 0, 0, 0, 0L);
> EV_SET(&kv, 0, 0, 0, 0, 0, 0LL);
> EV_SET(&kv, 0, 0, 0, 0, 0, 0U);
> EV_SET(&kv, 0, 0, 0, 0, 0, 0UL);
> EV_SET(&kv, 0, 0, 0, 0, 0, 0ULL);
> EV_SET(&kv, 0, 0, 0, 0, 0, (intptr_t)0);
> EV_SET(&kv, 0, 0, 0, 0, 0, (uintptr_t)0);
>
>
> return 0;
> }
This is not really an answer I was expecting as you are still not
saying anything of substance and your readers still have to
second-guess. Are you trolling?
I *guess* that the issue here is C++11 nullptr. If that's indeed the
case why don't just use a template with explicit specialization for
nullptr_t? Something along the lines of:
// c++ -S -O3 -std=c++11 -Wall -Wextra -Wold-style-cast ev.cpp
#include <sys/types.h>
#include <sys/event.h>
#if __cplusplus >= 201103L
#undef EV_SET /* from the header */
static inline void
EV_SET_(struct kevent *_kevp, uintptr_t _ident, uint32_t _filter,
uint32_t _flags, uint32_t _fflags, int64_t _data,
uintptr_t _udata)
{
_kevp->ident = _ident;
_kevp->filter = _filter;
_kevp->flags = _flags;
_kevp->fflags = _fflags;
_kevp->data = _data;
_kevp->udata = _udata;
}
template <typename _U>
static inline void
EV_SET(struct kevent *_kevp, uintptr_t _ident, uint32_t _filter,
uint32_t _flags, uint32_t _fflags, int64_t _data,
_U _udata)
{
EV_SET_(_kevp, _ident, _filter, _flags, _fflags, _data,
static_cast<uintptr_t>(_udata));
}
/* specialize for std::nullptr_t */
template <>
inline void
EV_SET(struct kevent *_kevp, uintptr_t _ident, uint32_t _filter,
uint32_t _flags, uint32_t _fflags, int64_t _data,
decltype(nullptr) _udata __unused)
{
EV_SET_(_kevp, _ident, _filter, _flags, _fflags, _data,
static_cast<uintptr_t>(0));
}
#endif
extern void consume(const struct kevent &kv);
int
main()
{
struct kevent kv;
EV_SET(&kv, 0, 0, 0, 0, 0, 0);
consume(kv);
EV_SET(&kv, 0, 0, 0, 0, 0, NULL);
consume(kv);
#if __cplusplus >= 201103L
EV_SET(&kv, 0, 0, 0, 0, 0, nullptr);
consume(kv);
#endif
EV_SET(&kv, 0, 0, 0, 0, 0, 0L);
consume(kv);
EV_SET(&kv, 0, 0, 0, 0, 0, 0LL);
consume(kv);
EV_SET(&kv, 0, 0, 0, 0, 0, 0U);
consume(kv);
EV_SET(&kv, 0, 0, 0, 0, 0, 0UL);
consume(kv);
EV_SET(&kv, 0, 0, 0, 0, 0, 0ULL);
consume(kv);
EV_SET(&kv, 0, 0, 0, 0, 0, static_cast<intptr_t>(0));
consume(kv);
EV_SET(&kv, 0, 0, 0, 0, 0, static_cast<uintptr_t>(0));
consume(kv);
EV_SET(&kv, 0, 0, 0, 0, 0, L'x');
consume(kv);
return 0;
}
-uwe
Home |
Main Index |
Thread Index |
Old Index