strange definition of enif_get_uint64

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

strange definition of enif_get_uint64

Caragea Silviu
Hello,

On a Mac OS 10.13.6 x64 in the osx headers the uint_64_t is defined as:

#ifndef _UINT64_T
#define _UINT64_T
typedef unsigned long long uint64_t;
#endif /* _UINT64_T */

But NIF function enif_get_uint64 is defined as

#  define enif_get_uint64 enif_get_ulong

which accepts an unsigned long

Any idea why is like this ?

Silviu

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: strange definition of enif_get_uint64

Mikael Pettersson-5
On Wed, Aug 28, 2019 at 11:30 PM Caragea Silviu <[hidden email]> wrote:

>
> Hello,
>
> On a Mac OS 10.13.6 x64 in the osx headers the uint_64_t is defined as:
>
> #ifndef _UINT64_T
> #define _UINT64_T
> typedef unsigned long long uint64_t;
> #endif /* _UINT64_T */
>
> But NIF function enif_get_uint64 is defined as
>
> #  define enif_get_uint64 enif_get_ulong
>
> which accepts an unsigned long
>
> Any idea why is like this ?

The definitiion of enif_get_uint64 is conditional on the size of C's
long type; the case you quoted only applies when long _is_ 64 bits.

(Typically long is 32 bits on 32-bit machines and 64 bits on 64-bit
machines, with long long always being 64 bits, but some OS:es
(Windows) insists on keeping long 32 bits even in 64-bit environments.
This is just one of many small details we have to handle when writing
C code that's supposed to work on many CPUs and OS:es.)
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: strange definition of enif_get_uint64

Caragea Silviu
But why not just using they definitions from stdint.h on platforms where this one exists ?

Idea is that the way is right now creates lot of conversions warnings if using NIF in mix with other libs that respects the <stdint.h> standard. And I need to put lot of casts to avoid them

Silviu

On Thu, Aug 29, 2019 at 10:40 AM Mikael Pettersson <[hidden email]> wrote:
On Wed, Aug 28, 2019 at 11:30 PM Caragea Silviu <[hidden email]> wrote:
>
> Hello,
>
> On a Mac OS 10.13.6 x64 in the osx headers the uint_64_t is defined as:
>
> #ifndef _UINT64_T
> #define _UINT64_T
> typedef unsigned long long uint64_t;
> #endif /* _UINT64_T */
>
> But NIF function enif_get_uint64 is defined as
>
> #  define enif_get_uint64 enif_get_ulong
>
> which accepts an unsigned long
>
> Any idea why is like this ?

The definitiion of enif_get_uint64 is conditional on the size of C's
long type; the case you quoted only applies when long _is_ 64 bits.

(Typically long is 32 bits on 32-bit machines and 64 bits on 64-bit
machines, with long long always being 64 bits, but some OS:es
(Windows) insists on keeping long 32 bits even in 64-bit environments.
This is just one of many small details we have to handle when writing
C code that's supposed to work on many CPUs and OS:es.)

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: strange definition of enif_get_uint64

Per Hedeland
On 2019-08-29 10:34, Caragea Silviu wrote:
> But why not just using they definitions from stdint.h on platforms where this one exists ?

+1. I guess the reason is historical, from back when stdint.h (part of
the C99 standard AFAIK) wasn't widely avaible or at least known, and
instead these 'configure'-based "private" typedefs were used. But
these days I really wonder if anyone is running Erlang on a platform
that doesn't have stdint.h.

> Idea is that the way is right now creates lot of conversions warnings if using NIF in mix with other libs that respects the <stdint.h> standard. And I need to put lot of casts to avoid them

Another problem is with cross compilation - in a native build,
'configure' can reliably determine the correct typedefs by running
sizeof()-tests, but for a cross build, the user has to tell it, and
had better get it right.

In fact just the other week I came across someone having ended up with
ErlNifUInt64 being an "unsigned long" in a cross build for a 32-bit
system, i.e. only 32 bits (perhaps whoever was to blame had done a
manual sizeof() test on the 64-bit build system).

Using stdint.h "just works" in my experience, both for portability (no
need for 'configure' for *that* at least) and for cross builds - it
would really be an improvement.

--Per

> Silviu
>
> On Thu, Aug 29, 2019 at 10:40 AM Mikael Pettersson <[hidden email] <mailto:[hidden email]>> wrote:
>
>     On Wed, Aug 28, 2019 at 11:30 PM Caragea Silviu <[hidden email] <mailto:[hidden email]>> wrote:
>      >
>      > Hello,
>      >
>      > On a Mac OS 10.13.6 x64 in the osx headers the uint_64_t is defined as:
>      >
>      > #ifndef _UINT64_T
>      > #define _UINT64_T
>      > typedef unsigned long long uint64_t;
>      > #endif /* _UINT64_T */
>      >
>      > But NIF function enif_get_uint64 is defined as
>      >
>      > #  define enif_get_uint64 enif_get_ulong
>      >
>      > which accepts an unsigned long
>      >
>      > Any idea why is like this ?
>
>     The definitiion of enif_get_uint64 is conditional on the size of C's
>     long type; the case you quoted only applies when long _is_ 64 bits.
>
>     (Typically long is 32 bits on 32-bit machines and 64 bits on 64-bit
>     machines, with long long always being 64 bits, but some OS:es
>     (Windows) insists on keeping long 32 bits even in 64-bit environments.
>     This is just one of many small details we have to handle when writing
>     C code that's supposed to work on many CPUs and OS:es.)
>
>
> _______________________________________________
> erlang-questions mailing list
> [hidden email]
> http://erlang.org/mailman/listinfo/erlang-questions
>

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: strange definition of enif_get_uint64

Mikael Pettersson-5
In reply to this post by Caragea Silviu
On Thu, Aug 29, 2019 at 10:35 AM Caragea Silviu <[hidden email]> wrote:
>
> But why not just using they definitions from stdint.h on platforms where this one exists ?

Presumably legacy from the times when stdint.h wasn't widely
available.  Also, in most cases it works fine to use equivalent (wrt
size and sign) but syntactically different types.

> Idea is that the way is right now creates lot of conversions warnings if using NIF in mix with other libs that respects the <stdint.h> standard. And I need to put lot of casts to avoid them

Presumably pointers or printf/scanf formats are involved, as e.g. a
64-bit long and a likewise 64-bit long long are fully
assignment-compatible, but pointers to them are not, and C compilers
like to warn when seeing "the wrong" printf/scanf format letter for an
argument even if they happen to match on the current target.

Yes, preference should be to use <stdint.h> and <inttypes.h> as far as
possible, but OTP's development cycles are limited.
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions