You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
__sizeof__ underreports size of 0 by 4 bytes #98159
sys.getsizeof and int#__sizeof__() both underreport the size of the 0 singleton by 4 bytes, due to _PyLong_DIGIT_INIT setting ob_size to 0 when initializing the 0 singleton, the correct value should be 1, since there is a single ob_digit stored, as I understand it.
Depending on the val passed it sets the the ob_size field of the immortal using the expression: ((val) == 0 ? 0 : ((val) > 0 ? 1 : -1))
2.1. When val is 0, this creates an _PyVarObject_IMMORTAL_INIT(&PyLong_Type, 0), which sets the underlying PyVarObject's ob_size to 0.
The ob_size should be 1 because ob_digit has one digit stored.
4.1. However, ob_size is set to 0, and this contributes to under-reporting the size of 0 by the sizeof(digit) which is 4
Your environment
CPython versions tested on: 3.8.14, 3.10.7
Operating system and architecture: Darwin 21.6.0 Darwin Kernel Version 21.6.0: Wed Aug 10 14:25:27 PDT 2022; root:xnu-8020.141.5~2/RELEASE_X86_6
I'm not entirely sure if this behaviour is incorrect, but my understanding is that ob_size should count the single digit stored in ob_digit. That is my premise for filing this as a bug.
This behavior looks like have a long history,
but the first trigger was from 36820dd by @mdickinson
@mdickinson
By this patch, The zero was set toPy_SIZE(v) = 0; since the sign is zero, was this intended? or it should be fixed to have ob_size = 1 even if the sign is 0?
or it should be fixed to have ob_size = 1 even if the sign is 0?
Definitely not: ob_size=0 is the correct value for a zero; IIRC, there are a good few places in the code that expect ob_size=0 for zero.
And yes, it's true that sys.getsizeof sometimes underreports for ints; that effect isn't limited to zero - there are lots of places in longobject.c where we allocate enough space and then don't reallocate after normalisation. That's a deliberate choice.
Activity
envp commentedon Oct 10, 2022
I'm not entirely sure if this behaviour is incorrect, but my understanding is that
ob_sizeshould count the singledigitstored inob_digit. That is my premise for filing this as a bug.Compiler explorer link: https://godbolt.org/z/rx7PbEYxd
corona10 commentedon Nov 6, 2022
This behavior looks like have a long history,
but the first trigger was from 36820dd by @mdickinson
@mdickinson
By this patch, The zero was set to
Py_SIZE(v) = 0;since the sign is zero, was this intended? or it should be fixed to have ob_size = 1 even if the sign is 0?corona10 commentedon Nov 6, 2022
@envp See also: #69408
mdickinson commentedon Nov 6, 2022
Definitely not:
ob_size=0is the correct value for a zero; IIRC, there are a good few places in the code that expectob_size=0for zero.And yes, it's true that
sys.getsizeofsometimes underreports for ints; that effect isn't limited to zero - there are lots of places inlongobject.cwhere we allocate enough space and then don't reallocate after normalisation. That's a deliberate choice.corona10 commentedon Nov 6, 2022
Thanks, Mark, I will close the issue.
The behavior looks like be intended.
cc @envp
envp commentedon Jan 4, 2023
Thanks Mark! That rationale definitely cleared it up for me.