Re: customized ERL_NIF_TERM type support
Sverker Eriksson <[email protected]> Tue, 11 Feb 2014 12:33:33 +0100
| Newsgroups | gmane.comp.lang.erlang.patches |
|---|---|
| Message-ID | <[email protected]> |
I agree. Shoot! /Sverker On 02/10/2014 08:28 PM, Daniel Goertzen wrote: > Regarding C++ types in extern "C": That is a very good question... > > I looked into the C++ standard and other documents. The answer is that > extern "C" just changes the default linkage to "C" instead of "C++". > Everything else remains the same, so you can still use the rest of C++ > inside an extern "C", but the linkage may impose some limitations (like no > function overloading). "C" linkage names only indicate the name the of the > function but not the parameter or return types like C++ linkage names. > > Now that I am a little more educated on linking and calling conventions, I > am uncomfortable with the patches I have suggested. Sure, they work on > linux with gcc, but will they work on MSVC? What about the other less > common unices? I think depending on linker looseness is brittle. > > As an alternate idea, I think I can generate inline C++ wrappers for the > whole NIF API and get a unique ERL_NIF_TERM type that way. It's not very > elegant, but everything gets resolved at compile time with no linker > tricks, and the compiler should flatten the wrapper away so that there is > no overhead. > > So, if you agree, I'd like to take this patch out back and shoot it. :) > > Dan. > > > > > > > On Mon, Feb 10, 2014 at 7:09 AM, Sverker Eriksson < > [email protected]> wrote: > >> The "hook" solution has an advantage I think. It leaves it up to the user >> to define the type and thereby to "make it work". >> >> I actually don't understand how you get this to work. How can you mix C++ >> types within a extern "C" declaration? >> >> /Sverker >> >> >> On 02/07/2014 08:21 PM, Daniel Goertzen wrote: >> >>> Thank you for your feedback. Maybe the "hook" approach I suggested is too >>> generic. My original patch from nifpp actually looks like this... >>> >>> #ifdef CPP11_UNIQUE_TERM_TYPE >>> enum class ERL_NIF_TERM : ERL_NIF_UINT; >>> #else >>> typedef ERL_NIF_UINT ERL_NIF_TERM; >>> #endif >>> >>> ...and then to use the typed enum in your c++ nif you write... >>> >>> #define CPP11_UNIQUE_TERM_TYPE >>> #include <erl_nif.h> >>> >>> >>> In the future ERL_NIF_TERM can be changed to a struct and the >>> CPP11_UNIQUE_TERM_TYPE option can just be ignored. What do you think? >>> >>> Cheers, >>> Dan. >>> >>> >>> On Fri, Feb 7, 2014 at 12:46 PM, Sverker Eriksson < >>> [email protected]> wrote: >>> >>> Thanks for the patch. >>>> I got one objection/question though. My C++ knowledge is a bit rusty but >>>> as I understand it >>>> the "enum class" construct demands that Type is an integer type. >>>> >>>> This is currently true for ERL_NIF_TERM but it might not be in the >>>> future. >>>> I earlier tried to define ERL_NIF_TERM as >>>> >>>> typedef struct { int x; } ERL_NIF_TERM; >>>> >>>> to get stronger type checking even for C. I reverted that due to bad >>>> performance >>>> as gcc has different calling conventions for int and struct {int}. >>>> However, future compilers >>>> might be better at passing struct{int} by value in which case we might >>>> want to change >>>> the definition of ERL_NIF_TERM. >>>> >>>> What then? Do we ignore CUSTOM_NIF_TERM_TYPE in such a scenario? >>>> >>>> >>>> /Sverker, Erlang/OTP >>>> >>>> >>>> >>>> On 02/07/2014 06:34 PM, Daniel Goertzen wrote: >>>> >>>> When writing NIFs in C++, it is impossible to employ C++ function >>>> overloading because the underlying type of ERL_NIF_TERM is "unsigned >>>> int". >>>> For example: >>>> >>>> // won't compile :( >>>> #include <erl_nif.h> >>>> void my_func(ERL_NIF_TERM a) {...} >>>> void my_func(unsigned int a) {...} >>>> >>>> >>>> This patch allows NIF authors to mutate the type of ERL_NIF_TERM by >>>> defining the macro CUSTOM_NIF_TERM_TYPE(). In the example below, the >>>> underlying unsigned integer type gets wrapped as a C++11 typed >>>> enumeration. The type of ERL_NIF_TERM is now unique and can be used in >>>> overloaded functions. >>>> >>>> // compiles! :) >>>> #define CUSTOM_NIF_TERM_TYPE(Type) enum class ERL_NIF_TERM : Type {}; >>>> #include <erl_nif.h> >>>> void my_func(ERL_NIF_TERM a) {...} >>>> void my_func(unsigned int a) {...} >>>> >>>> >>>> The patch has no impact on erl_nif.h if CUSTOM_NIF_TERM_TYPE is not >>>> defined >>>> (other than flipping the definition order of ERL_NIF_TERM and >>>> ERL_NIF_UINT). >>>> >>>> A similar approach has been used on my C++11 NIF wrapper ( >>>> https://github.com/goertzenator/nifpp). The wrapper requires manual >>>> >>>> installation of a similar patch, and I would love to remove that >>>> requirement. >>>> >>>> Regards, >>>> Dan. >>>> >>>> >>>> >>>> >>>> _______________________________________________ >>>> erlang-patches mailing [email protected]:// >>>> erlang.org/mailman/listinfo/erlang-patches >>>> >>>> >>>> >>>> _______________________________________________ erlang-patches mailing list [email protected] http://erlang.org/mailman/listinfo/erlang-patches