diff options
author | Karl Williamson <khw@cpan.org> | 2022-05-18 09:07:49 -0600 |
---|---|---|
committer | Karl Williamson <khw@cpan.org> | 2022-05-20 14:32:29 -0600 |
commit | e815fc9e521a3f7203f08588dfcd102261bdacd7 (patch) | |
tree | 8bcb46f28c5a7d9c8995ab8e54fd569246a64c2e | |
parent | 550c0c1fea3148fcdb3c19fa616d4902b1f3058d (diff) | |
download | perl-e815fc9e521a3f7203f08588dfcd102261bdacd7.tar.gz |
perlapi: Clean up some AV documentation
The consolidation of newAV with newAV_alloc_xz? included nonsensical
juxtapositions. This cleans that up, adds a bit of markup, moves the
function implementing the newAV_alloc ones to internal, as there are no
CPAN uses, and we prefer the macro interface.
-rw-r--r-- | av.c | 21 | ||||
-rw-r--r-- | av.h | 100 | ||||
-rw-r--r-- | embed.fnc | 2 |
3 files changed, 79 insertions, 44 deletions
@@ -210,9 +210,9 @@ Perl_av_extend_guts(pTHX_ AV *av, SSize_t key, SSize_t *maxp, SV ***allocp, =for apidoc av_fetch Returns the SV at the specified index in the array. The C<key> is the -index. If lval is true, you are guaranteed to get a real SV back (in case +index. If C<lval> is true, you are guaranteed to get a real SV back (in case it wasn't real before), which you can then modify. Check that the return -value is non-null before dereferencing it to a C<SV*>. +value is non-NULL before dereferencing it to a C<SV*>. See L<perlguts/"Understanding the Magic of Tied Hashes and Arrays"> for more information on how to use this function on tied arrays. @@ -395,17 +395,22 @@ Perl_av_store(pTHX_ AV *av, SSize_t key, SV *val) /* =for apidoc av_new_alloc +This implements L<perlapi/C<newAV_alloc_x>> +and L<perlapi/C<newAV_alloc_xz>>, which are the public API for this +functionality. + Creates a new AV and allocates its SV* array. -This is similar to but more efficient than doing: +This is similar to, but more efficient than doing: AV *av = newAV(); av_extend(av, key); The size parameter is used to pre-allocate a SV* array large enough to -hold at least elements 0..(size-1). size must be at least 1. +hold at least elements C<0..(size-1)>. C<size> must be at least 1. -The zeroflag parameter controls whether the array is NULL initialized. +The C<zeroflag> parameter controls whether or not the array is NULL +initialized. =cut */ @@ -432,9 +437,9 @@ Perl_av_new_alloc(pTHX_ SSize_t size, bool zeroflag) /* =for apidoc av_make -Creates a new AV and populates it with a list of SVs. The SVs are copied -into the array, so they may be freed after the call to C<av_make>. The new AV -will have a reference count of 1. +Creates a new AV and populates it with a list (C<**strp>, length C<size>) of +SVs. A copy is made of each SV, so their refcounts are not changed. The new +AV will have a reference count of 1. Perl equivalent: C<my @new_array = ($scalar1, $scalar2, $scalar3...);> @@ -112,64 +112,94 @@ If all you need is to look up an array element, then prefer C<av_fetch>. =for apidoc_item newAV_alloc_x =for apidoc_item newAV_alloc_xz -These all create a new AV, setting the reference count to 1. They differ -in the allocation and population of the array of SV*s that always -accompanies a non-empty AV. +These all create a new AV, setting the reference count to 1. -The Perl equivalent is approximately C<my @array;>. +As background, an array consists of three things: -newAV does not allocate a SV* array. - AV *av = newAV(); +=over + +=item 1. + +A data structure containing information about the array as a whole, such as its +size and reference count. + +=item 2. + +A C language array of pointers to the individual elements. These are treated +as pointers to SVs, so all must be castable to SV*. + +=item 3. + +The individual elements themselves. These could be, for instance, SVs and/or +AVs and/or HVs, etc. + +=back + +An empty array need only have the first data structure, and all these functions +create that. They differ in what else they do, as follows: + +=over + +=item C<newAV> form + +=for comment +'form' above and below is because otherwise have two =items with the same name, +can't link to them. + +This does nothing beyond creating the whole-array data structure. +The Perl equivalent is approximately S<C<my @array;>> -This is very useful when an AV is required, but populating it may be -deferred, or even never actually take place. (Memory is not allocated -unnecessarily.) +This is useful when the minimum size of the array could be zero (perhaps there +are likely code paths that will entirely skip using it). -Subsequent SV* array allocation would be performed via C<L</av_extend>>. -This might be called directly: - av_extend(av, key); +If the array does get used, the pointers data structure will need to be +allocated at that time. This will end up being done by L</av_extend>>, +either explicitly: + + av_extend(av, len); + +or implicitly when the first element is stored: -Or it might be called implicitly when the first element is stored: (void)av_store(av, 0, sv); Unused array elements are typically initialized by C<av_extend>. (Only core maintainers should have need to concern themseleves with when that -is not the case. Refer to F<av.h> and F<av.c> for the differences between +is not the case. Refer to F<av.h> and F<av.c> for the differences between real and fake AVs.) -In contrast, when an AV is created for immediate population with a known -(or likely) number of elements, it is more efficient to immediately -allocate a SV* array of the necessary size. (This avoids inefficient use -of C<av_extend> and the potential for the first allocation being too small -and then having to resize it.) +=item C<newAV_alloc_x> form + +This effectively does a C<newAV> followed by also allocating (uninitialized) +space for the pointers array. This is used when you know ahead of time the +likely minimum size of the array. It is more efficient to do this than doing a +plain C<newAV> followed by an C<av_extend>. + +Of course the array can be extended later should it become necessary. + +C<size> must be at least 1. + +=item C<newAV_alloc_xz> form -For that scenario, newAV_alloc_x and newAV_alloc_xz can be used to create -an AV and allocate a SV* array to fit the specified number of elements. -(As a result, these macros MUST NOT be called with a size less than 1.) +This is C<newAV_alloc_x>, but initializes each pointer in it to NULL. This +gives added safety to guard against them being read before being set. If you +know now what those elements should be, instead use L</C<av_make>>. -newAV_alloc_x does not initialize the array elements - and so the -expectation is that all will be initialized elsewhere prior to any -potentials reads. newAV_alloc_xz does initialize the array elements. +C<size> must be at least 1. + +=back The following examples all result in an array that can fit four elements (indexes 0 .. 3): AV *av = newAV(); - av_extend(av, 1); - - AV *av = newAV(); av_extend(av, 3); - AV *av = newAV_alloc_xz(4); - AV *av = newAV_alloc_x(4); -In the newAV_alloc_x case, the array elements will not be initialized -and their contents are therefore undefined. In the other cases, the -array elements are all initialized. + AV *av = newAV_alloc_xz(4); -In contrast, the following examples allocate an SV* array that is only -guaranteed to fit one element: +In contrast, the following examples allocate an array that is only guaranteed +to fit one element without extending: AV *av = newAV_alloc_x(1); AV *av = newAV_alloc_xz(1); @@ -640,7 +640,7 @@ CipdR |SV** |av_fetch_simple|NN AV *av|SSize_t key|I32 lval Apd |void |av_fill |NN AV *av|SSize_t fill ApdR |SSize_t|av_len |NN AV *av ApdR |AV* |av_make |SSize_t size|NN SV **strp -ApdR |AV* |av_new_alloc |SSize_t size|bool zeroflag +CpdR |AV* |av_new_alloc |SSize_t size|bool zeroflag p |SV* |av_nonelem |NN AV *av|SSize_t ix Apd |SV* |av_pop |NN AV *av Apdoe |void |av_create_and_push|NN AV **const avp|NN SV *const val |