World: r3wp
[Red] Red language group
older newer | first last |
Dockimbel 18-Jun-2011 [2121x6] | Well, I have already answered that question above. I am sorry if that change breaks existing code. Once again, the C void pointer is a very confusing concept that should not be used outside of C language. If you refer to a C void pointer without any context, it is just a memory address, so integer! (or handle!) would be the closest corresponding concept. If you refer to a C function returning a void pointer like malloc(), the closest transposition in Red/System would be ALLOCATE returning a byte! pointer. |
Malloc() allocates a memory region that granularity is by default a byte (until you cast is to something else). | |
So, in summary, there is no 1 to 1 transposition of the C void pointer concept in Red/System, it is 1 to 2 (or more), depending on the context. | |
If you would write a C function such as: void *bar() { return((void *)&foo);) where foo would be another function. If I had to make a binding to this function from Red, I would use integer! (or preferably the handle! macro) to define the return value. | |
Six months ago, I wanted to introduce an address! type to be the equivalent of C void pointer. It would have worked as an integer!. But as it would have been only used to in C binding definitions, I thought it would be a waste to have a first-class datatype just for that, when integer!, pointer! [...], or a macro could do the same job. | |
If [pointer! [byte!]] could do the job and make C coders happy, I will add it to Red/System. | |
Kaj 18-Jun-2011 [2127x5] | I'm not concerned with all that here. Let me make this very concrete. In runtime/common.reds, changing |
#define byte-ptr! c-string! | |
to | |
#define byte-ptr! pointer [integer!] | |
Would solve all my current concerns | |
Dockimbel 18-Jun-2011 [2132] | Well, this is certainly not the right definition a byte! pointer. :-) Can't you wait until monday when all the current issues regarding NULL and documentation will be fixed? |
Kaj 18-Jun-2011 [2133x3] | We have been aware that pointer [integer!] does not accurately describe a pointer [byte!] but you don't want to implement that in the current development cycle and that's fair enough. It's only a cosmetic problem right now |
Originally I though binary! was going to fulfill this role, but it was removed | |
Will the NULL enhancement change the types handled by ALLOCATE and FREE to one generic pointer definition? Let's stop calling it void, but instead variant, which it really is | |
Dockimbel 18-Jun-2011 [2136] | Binary!: you're right, that was an option I considered at the beginning. But I thought that it would be even more confusing for REBOL coders. |
Kaj 18-Jun-2011 [2137x2] | It felt very natural to me |
We're in a morass now ;-) | |
Dockimbel 18-Jun-2011 [2139x4] | Think about ppl that would have complained about LENGTH? not working on binary! type. ;-) |
No, that would not change the types of ALLOCATE and FREE, I would only change them to pointer! [byte!] when it will be available. | |
There is no generic pointer in Red/System. | |
Even if binary! was there, it would work as a byte! pointer. | |
Kaj 18-Jun-2011 [2143x3] | I thought so, so ALLOCATE and FREE will still deliver types that I wouldn't expect from them, and that effectively introduce an extra definition of a variant pointer |
The LENGTH? example is interesting, because people will now use it on an allocated binary, expecting that it's zero-terminated, and even if it is, the expected length will be off by one | |
Or much more if there's a zero somewhere in the middle | |
Dockimbel 18-Jun-2011 [2146] | You're extrapolating from the error message. The definition says "byte-ptr!" not "c-string!". |
Kaj 18-Jun-2011 [2147x2] | Yes, that's a fundamental problem with a preprocessor |
But the more tangible problem is that currently, you don't have to cast when you allocate a string, and that will change when a proper byte pointer is introduced | |
Dockimbel 18-Jun-2011 [2149] | Right, but this is an alpha, not a v1. Maybe I should postpone the beta announcement by a month or two? |
Kaj 18-Jun-2011 [2150x2] | You don't have to, because the fix is only half a line, and I don't need it before Monday |
Anyway, I've brought forward my concerns; that's all I can do | |
Dockimbel 18-Jun-2011 [2152] | Well, thanks for the feedback, I will think about all the possible options. |
Kaj 18-Jun-2011 [2153x2] | OK, thanks |
I see you're using byte! definitions for C functions that take integer! parameters. Is that guaranteed to be interpreted as an integer? | |
Dockimbel 18-Jun-2011 [2155] | Are you referring to memset() wrapper? |
Kaj 18-Jun-2011 [2156] | Yes. What's the conversion applied there? |
Dockimbel 18-Jun-2011 [2157x2] | No conversion at all. The memset case is a old C oddity that never got fixed. It should have a byte in the declaration instead of int. The algorithm in memset uses a byte and not an int, so the Red/System binding is not only safe, but also cleaner than the C one. The memset oddity is explained there: http://stackoverflow.com/questions/5919735/why-does-memset-take-an-int-instead-of-a-char |
Jocko, answering your questions: - is this correct ? Yes, I tested it here, works flawlessly. - how and where de-allocate the c-string ? Same as in C, when you don't need it anymore. So in your code example, it would be after "print res". - why the end-string symbol is not added automatically ? Red/System is a low-level language, it treats c-string! as C does with string, the trailing zero is only a convention. If ReadConsole() doesn't add a trailing zero, only the programmer knows if and where it should be added. Red/System can only add automatically trailing zero on literal c-string! because, in that case, it can easily guess where the c-string! ends. | |
Kaj 18-Jun-2011 [2159x7] | Doc, thanks for the link; that's informative |
I've updated both my C library binding and my 0MQ binding to work with the latest Red | |
A lot of changes were needed, most of them for the stricter checking | |
Callbacks can now be passed to imported functions with fully defined specs. However, function specs can not be defined as the return value of an imported function: | |
on-signal: "signal" [ ; Register handlers for receiving system signals. signal [integer!] handler [function! [signal [integer!]]] ; Flag or callback ; return: [function! [signal [integer!]]] return: [handle!] ] | |
Also, callbacks can't be passed as such to native functions. In some cases they can still be passed as unspecified handles, but those can't be cast to callback functions. I have a wrapper for atexit() that is now impossible to define: | |
on-quit: func [ ; Register handler for normal program termination. ; handler [function! []] ; Callback handler [handle!] ; Callback return: [logic!] ][ not as-logic _on-quit handler ] | |
jocko 19-Jun-2011 [2166] | Doc, thanks for yor answers |
Dockimbel 19-Jun-2011 [2167x4] | Kaj: function! is just a pseudo-type (not a first-class type) that was introduced just to be able to verify callback signatures when passed to an external library. |
I will have a look today on your issue and see if allowing function! to be passed as argument and returned as value is safe and side-effect free in the current state of the implementation. | |
Kaj: on Windows, it is possible to use _get_osfhandle() to retrieve the file handle for stdin/out/err (http://msdn.microsoft.com/en-us/library/ks2530z6.aspx) | |
I can't find an equivalent in UNIX world. | |
older newer | first last |