Обсуждение: Why not use the calloc to replace malloc?
HI team,
I'm a newbie to the postgres.
When I learn the code of libpq, the achieve of PQmakeEmptyPGresult, cause my curiosity.
The old version code:
PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
{
PGresult *result;
result = (PGresult *) malloc(sizeof(PGresult));
if (!result)
return NULL;
result->ntups = 0;
result->numAttributes = 0;
result->attDescs = NULL;
result->tuples = NULL;
result->tupArrSize = 0;
result->numParameters = 0;
result->paramDescs = NULL;
result->resultStatus = status;
result->cmdStatus[0] = '\0';
result->binary = 0;
result->events = NULL;
result->nEvents = 0;
result->errMsg = NULL;
result->errFields = NULL;
result->errQuery = NULL;
result->null_field[0] = '\0';
result->curBlock = NULL;
result->curOffset = 0;
result->spaceLeft = 0;
result->memorySize = sizeof(PGresult);
/* .............
*/
return result;
} My version:
PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
{
PGresult *result;
result = (PGresult *) calloc(sizeof(PGresult));
if (!result)
return NULL;
result->memorySize = sizeof(PGresult);
/* .............
*/
return result;
} Why not have a change?I don't know.
I'm a newbie, so I don't think I can commit a patch for postgres, just instead of send mail to ask.
Yours,
Wenyi.
Wen Yi <chuxuec@outlook.com> writes: > [ use calloc to replace zeroing fields individually ] The reason we like to do it like that is that it provides greppability, that is you can search the source code to see where a particular field is initialized or modified. The backend code is often intentionally inefficient in this way: you can find a lot of places that do makeNode(some-node-type) and then zero out fields within the node, even though makeNode() always provides a zeroed-out struct. An important reason why this is a good idea is that the code isn't dependent on whether the particular value you need to initialize the field to happens to be bitwise zeros or something else. People have complained about this practice off-and-on, but no one has provided any evidence that there's a significant performance cost. The maintenance benefits are real though. regards, tom lane
On Sat, 22 Apr 2023, Tom Lane wrote: >Wen Yi <chuxuec@outlook.com> writes: >> [ use calloc to replace zeroing fields individually ] […] >People have complained about this practice off-and-on, but no one has >provided any evidence that there's a significant performance cost. >The maintenance benefits are real though. Oh, interesting ;-) Thanks for this explanation. Another data point is: calloc is not correct for pointer fields, you have to manually assign NULL to them afterwards still, because NULL doesn’t have to be represented by all-zero bytes (e.g. TenDRA supports having 0x55555555 as NULL pointer as an option). bye, //mirabilos -- 15:41⎜<Lo-lan-do:#fusionforge> Somebody write a testsuite for helloworld :-)
Thorsten Glaser <tg@evolvis.org> writes: > On Sat, 22 Apr 2023, Tom Lane wrote: >> The maintenance benefits are real though. > Oh, interesting ;-) Thanks for this explanation. > Another data point is: calloc is not correct for pointer fields, > you have to manually assign NULL to them afterwards still, because > NULL doesn’t have to be represented by all-zero bytes (e.g. TenDRA > supports having 0x55555555 as NULL pointer as an option). Yeah, according to the letter of the C standard you shouldn't assume that NULL is physically the same as zero. We've blithely ignored that though --- there are lots of places that, for example, assume that palloc0() of an array of pointers will produce pointer values that are NULL. I don't see any real-world benefit in insisting on looping over such an array to set the pointers individually. But this is a good comparison point, because it illuminates one aspect of the maintenance argument. Suppose you want to add a field to struct Foo, and that field often or always needs to start out with a nonzero value. With our existing practice, grepping for places that assign to the adjacent fields will generally find all the places you need to touch. If we relied more on calloc or palloc0 to initialize fields, you'd have a harder time. People would be pushed into contorting their data representation choices so that fields could start out as physically zero, and that would lead to things like odd, inconsistent choices of boolean flag polarity. regards, tom lane