From 48d21358f7bd06d60aaa4f913cd417b5eafa3fc0 Mon Sep 17 00:00:00 2001 From: Richard Leach Date: Sun, 8 Aug 2021 21:53:33 +0100 Subject: av.h - better document newAV_alloc_x/newAV_alloc_xz --- av.h | 62 ++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 22 deletions(-) (limited to 'av.h') diff --git a/av.h b/av.h index 23902b41e9..526699066b 100644 --- a/av.h +++ b/av.h @@ -109,32 +109,46 @@ If all you need is to look up an array element, then prefer C. /* =for apidoc newAV +=for apidoc_item newAV_alloc_x +=for apidoc_item newAV_alloc_xz -Creates a new AV. The reference count is set to 1. +These all create a new AV, setting the reference count to 1. They differ +in when and how an accompanying SV* array is allocated and initialized. -Perl equivalent: C. +The Perl equivalent is approximately C. -=cut -*/ +newAV does not allocate a SV* array. + AV *av = newAV(); -#define newAV() MUTABLE_AV(newSV_type(SVt_PVAV)) +This is very useful when an AV is required, but population of it may be +deferred, or even never actually take place. (Memory is not allocated +unnecessarily.) -/* -=for apidoc newAV_alloc_x -=for apidoc newAV_alloc_xz +Subsequent SV* array allocation would be performed via av_extend. This +might be called directly: + av_extend(av, key); -Similar to newAV(), but a SV* array is also allocated. +Or it might be called implicitly when the first element is stored: + (void)av_store(av, 0, sv); -This is similar to but more efficient than doing: +Whether or not any as-yet-untouched array elements are initialized by +av_extend depends upon whether the array is "real" at the time. - AV *av = newAV(); - av_extend(av, key); +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 av_extend and the potential for the first allocation being too small +and then having to resize it.) + +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.) -Note that the actual size requested is allocated. This is unlike -av_extend(), which takes the maximum desired array index (AvMAX) as its -"key" parameter, and enforces a minimum value for that of 3. +newAV_alloc_x does not initialize the array elements - and so the +expectation is that all should be initialized elsewhere prior to any +potentials reads. newAV_alloc_xz does initialize the array elements. -In other words, the following examples all result in an array that can +As an example, the following examples all result in an array that can fit four elements (indexes 0 .. 3): AV *av = newAV(); @@ -143,20 +157,24 @@ fit four elements (indexes 0 .. 3): AV *av = newAV(); av_extend(av, 3); + AV *av = newAV_alloc_xz(4); + AV *av = newAV_alloc_x(4); -Whereas this will result in an array that can only fit one element: +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_x(1); +In contrast, the following examples allocate an SV* array that is only +guaranteed to fit one element: -newAV_alloc_x does not initialize the array with NULL pointers. -newAV_alloc_xz does do that initialization. - -These macros MUST NOT be called with a size less than 1. + AV *av = newAV_alloc_x(1); + AV *av = newAV_alloc_xz(1); =cut */ +#define newAV() MUTABLE_AV(newSV_type(SVt_PVAV)) #define newAV_alloc_x(size) av_new_alloc(size,0) #define newAV_alloc_xz(size) av_new_alloc(size,1) -- cgit v1.2.1