STINNER Victor <vstin...@python.org> added the comment:
Example: --- struct Point { int x; int y; int z; }; int main() { struct Point p = {1}; return p.y; } --- gcc -O0 produces this machine code which sets p.y to 0 and p.z to 0: --- Dump of assembler code for function main: 0x0000000000401106 <+0>: push rbp 0x0000000000401107 <+1>: mov rbp,rsp 0x000000000040110a <+4>: mov QWORD PTR [rbp-0xc],0x0 0x0000000000401112 <+12>: mov DWORD PTR [rbp-0x4],0x0 0x0000000000401119 <+19>: mov DWORD PTR [rbp-0xc],0x1 0x0000000000401120 <+26>: mov eax,DWORD PTR [rbp-0x8] 0x0000000000401123 <+29>: pop rbp 0x0000000000401124 <+30>: ret --- gcc -O3 heavily optimize the code, it always return 0, it doesn't return a random value from the stack: --- (gdb) disassemble main Dump of assembler code for function main: 0x0000000000401020 <+0>: xor eax,eax 0x0000000000401022 <+2>: ret --- The "C99 Standard 6.7.8.21" says: If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration. The C99 standard says that p.y and p.z must be set to 0. I'm talking about the specific C syntax of a structure static initialization: "struct MyStruct x = {...};". If "Py_buffer data = {NULL, NULL};" is allocated on the stack, all "data" Py_buffer members are set to 0 or NULL: typedef struct bufferinfo { void *buf; PyObject *obj; /* owned reference */ Py_ssize_t len; Py_ssize_t itemsize; /* This is Py_ssize_t so it can be pointed to by strides in simple case.*/ int readonly; int ndim; char *format; Py_ssize_t *shape; Py_ssize_t *strides; Py_ssize_t *suboffsets; void *internal; } Py_buffer; If we want to add a version member to this structure, I would suggest to enforce the usage of a static initialization macro or an initialization function, like: "Py_buffer data; PyBuffer_Init(&data);" or "Py_buffer data = PyBuffer_STATIC_INIT;" The problem of the macro is that it is not usable on Python extensions was are not written in C or C++ (or more generally to extensions which cannot use macros). -- A different approach is to use an API which allocates a Py_buffer on the heap memory, so if the structure becomes larger tomorrow, an old built C extensions continues to work: Py_buffer *data = PyBuffer_New(); // ... use *data ... PyBuffer_Free(data); PyBuffer_New() can initialize the version member and allocates the proper memory block size. The best is if the "... use *data ..." part is only done with function calls :-) ---------- _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue45459> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com