Todd (and others), So a few things.
1) JJ's example worked by chance. (sorry JJ). It worked because it just so happens that either his OS zero filled the block he was allocated by the allocator or because he didn't reuse the block that was given to him initially by the allocator. 2) If you assume that the function set_foo($array) expects a NULL terminated string, only then is the documentation a problem. However, there's not enough information in the C prototype to make this assumption. There's also no set_foo($array) function body to explore. # C prototype is void set_foo(const char *) All this says is that the subroutine is receiving a pointer to memory containing bytes and nothing more. The body of the function _may_ simply check the first 3 bytes. This is up to the reader to ascertain. 3) As for a documentation update, I'm unsure if it's required. The example is not only perfectly valid raku, it's also perfectly valid C. Perhaps something could be added to remove whatever ambiguity you perceive, but you argument stems from something that isn't necessarily true in this example and that's the function set_foo($array) expects a NULL terminated string. ~Paul On Fri, Jan 17, 2020 at 5:29 PM ToddAndMargo via perl6-users < perl6-us...@perl.org> wrote: > Hi JJ, > > Please be my hero. > > I won't call you any goofy names out of > affection and friendship, as others will get > their nickers in a twist. > > This is from a previous conversation we had concerning > the mistake in > > https://docs.raku.org/language/nativecall#index-entry-nativecall > > my $string = "FOO"; > ... > my $array = CArray[uint8].new($string.encode.list); > > > Todd: > By the way, "C String" REQUIRES a nul at the end: > an error in the NativeCall documentation. > > JJ: > No, it does not. And even if it did, it should better > go to the C, not Raku, documentation > > > And that would be a "String Literal", which is NOT > a C String. And C's documentation is precise and > clear (n1570). It is not their problem. It > is a mistake in NativeCall's documentation. > > Without the nul at the end, the string is considered > "undefined". > > The C guys have been helping me with definitions. Chapter and > verse would be : > > INTERNATIONAL STANDARD ©ISO/IEC ISO/IEC 9899:201x > Programming languages — C > http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf > > 5.2.1 Character sets > 7.1.1 Definitions of terms > 6.7.9,p14 Semantics > > Here is your String Literal, which you are confusing > with a c string: > > 6.7.9,p14 states: > > An array of character type may be initialized by a > character string literal or UTF−8 string literal, > optionally enclosed in braces. Successive bytes > of the string literal (including the terminating > null character if there is room or if the array > is of unknown size) initialize the elements of > the array. > > So there is the unnecessary nul you speak of, except, > again, it is not a C String. So you do have a > somewhat of a point, although not a good one as > it will throw those trying to use the docs into > a state of confusion wondering what is going wrong, > as it did me. > > It about killed me to figure it our myself. I > don't want others to go through the same pain > over a simple mistake in the documentation. > > Now the C guys told me that the reason why I am not > getting anywhere with you is that I provided a bad > example. They proceeded to give me an example > that precisely shows the careening make by > the mistake in the documentation: > > > An example of an unterminated C string: > > On 2020-01-17 13:21, Bart wrote: > > > > <t2.c> > > #include <stdio.h> > > > > void foo(const char *s) > > { > > for (int i=0; i<10; ++i) > > printf("%d ",*s++); > > puts(""); > > > > } > > > > int main(void) > > { > > char str[3] = "FOO"; > > foo(str); > > } > > </t2.c> > > > To compile: > gcc -o t2 t2.c > > To Run > t2 > > > > This prints the 3 characters codes of F,O,O in the string, plus 7 > > bytes that follow. Results on various compilers are as follows: > > > > bcc: 70 79 79 0 0 0 0 0 0 0 > > tcc: 70 79 79 80 -1 18 0 0 0 0 > > gcc -O0: 70 79 79 112 -14 48 0 0 0 0 > > gcc -O3: 70 79 79 2 0 0 0 0 0 0 > > lcc: 70 79 79 0 0 0 0 0 0 0 > > dmc: 70 79 79 0 -120 -1 24 0 25 33 > > clang -O0: 70 79 79 16 6 64 0 0 0 0 > > clang -O2: 70 79 79 0 48 -120 73 6 -19 127 > > msvc: 70 79 79 -29 -9 127 0 0 0 0 > > > > The 70, 79, 79 are the F, O and O codes. When those 3 happen to > > be followed by 0, then it will appear to work. > > > > That is 4 out of 9, but the other 5 won't work. What follows > > after FOO is undefined and could be anything, although a random 0 is > common. > > > > JJ! He ran it through NINE C compilers! The careening > is OBVIOUS! > > And this mistake is very easy to fix: > > Change > my $array = CArray[uint8].new($string.encode.list); > to > my $array = CArray[uint8].new($string.encode.list, 0); > > THREE characters `, 0` and it is fixed! And you are > are finally conforming to n1570. And you will be > my ever living hero! (Watch some take offense to that!) > > Have I still not convinced you? THREE CHARACTERS !!!! > > Sorry for being such a pest about this. It about killed > me to figure out. > > Please be my hero. > > -T > > Retrievers are better looking than Labs. (I can't > wait for the hate mail over that!) > -- __________________ :(){ :|:& };: