[Python-checkins] r55016 - peps/trunk/pep-0000.txt peps/trunk/pep-3123.txt

martin.v.loewis python-checkins at python.org
Sun Apr 29 15:42:20 CEST 2007


Author: martin.v.loewis
Date: Sun Apr 29 15:42:17 2007
New Revision: 55016

Added:
   peps/trunk/pep-3123.txt   (contents, props changed)
Modified:
   peps/trunk/pep-0000.txt
Log:
Add PEP 3123.


Modified: peps/trunk/pep-0000.txt
==============================================================================
--- peps/trunk/pep-0000.txt	(original)
+++ peps/trunk/pep-0000.txt	Sun Apr 29 15:42:17 2007
@@ -119,6 +119,7 @@
  S  3119  Introducing Abstract Base Classes            GvR, Talin
  S  3120  Using UTF-8 as the default source encoding   von Löwis
  S  3121  Module Initialization and finalization       von Löwis
+ S  3123  Making PyObject_HEAD conform to standard C   von Löwis
  S  3141  A Type Hierarchy for Numbers                 Yasskin
 
  Finished PEPs (done, implemented in Subversion)
@@ -480,6 +481,7 @@
  S  3120  Using UTF-8 as the default source encoding   von Löwis
  S  3121  Module Initialization and finalization       von Löwis
  SR 3122  Delineation of the main module               Cannon
+ S  3123  Making PyObject_HEAD conform to standard C   von Löwis
  S  3141  A Type Hierarchy for Numbers                 Yasskin
 
 

Added: peps/trunk/pep-3123.txt
==============================================================================
--- (empty file)
+++ peps/trunk/pep-3123.txt	Sun Apr 29 15:42:17 2007
@@ -0,0 +1,138 @@
+PEP: 3123
+Title: Making PyObject_HEAD conform to standard C
+Version: $Revision$
+Last-Modified: $Date$
+Author: Martin v. Löwis <martin at v.loewis.de>
+Status: Draft
+Type: Standards Track
+Content-Type: text/x-rst
+Created: 27-Apr-2007
+Python-Version: 3.0
+Post-History:
+
+Abstract
+========
+
+Python currently relies on undefined C behavior, with its
+usage of PyObject_HEAD. This PEP proposes to change that
+into standard C.
+
+Rationale
+=========
+
+Standard C defines that an object must be accessed only through a
+pointer of its type, and that all other accesses are undefined
+behavior, with a few exceptions. In particular, the following
+code has undefined behavior::
+
+  struct FooObject{
+    PyObject_HEAD
+    int data;
+  };
+
+  PyObject *foo(struct FooObject*f){
+   return (PyObject*)f;
+  }
+
+  int bar(){
+   struct FooObject *f = malloc(sizeof(struct FooObject));
+   struct PyObject *o = foo(f);
+   f->ob_refcnt = 0;
+   o->ob_refcnt = 1;
+   return f->ob_refcnt;
+  }
+
+The problem here is that the storage is both accessed as
+if it where struct PyObject, and as struct FooObject.
+
+Historically, compilers did not cause any problems with this
+code. However, modern compiler use that clause as an 
+optimization opportunity, finding that f->ob_refcnt and
+o->ob_refcnt cannot possibly refer to the same memory, and
+that therefore the function should return 0, without having
+to fetch the value of ob_refcnt at all in the return
+statement. For GCC, Python now uses -fno-strict-aliasing
+to work around that problem; with other compilers, it
+may just see undefined behavior. Even with GCC, using
+-fno-strict-aliasing may pessimize the generated code
+unnecessarily.
+
+Specification
+=============
+
+Standard C has one specific exception to its aliasing rules precisely
+designed to support the case of Python: a value of a struct type may
+also be accessed through a pointer to the first field. E.g. if a
+struct starts with an int, the struct\* may also be cast to an int\*,
+allowing to write int values into the first field.
+
+For Python, PyObject_HEAD and PyObject_VAR_HEAD will be changed
+to not list all fields anymore, but list a single field of type
+PyObject/PyVarObject::
+
+  typedef struct _object{
+    _PyObject_HEAD_EXTRA
+    Py_ssize_t ob_refcnt;
+    struct _typeobject *ob_type;
+  }PyObject;
+
+  typedef struct {
+    PyObject ob_base;
+    Py_ssize_t ob_size;
+  } PyVarObject;
+
+  #define PyObject_HEAD        PyObject ob_base;
+  #define PyObject_VAR_HEAD    PyVarObject ob_base;
+
+Types defined as fixed-size structure will then include PyObject
+as its first field; variable-sized objects PyVarObject. E.g.::
+
+  typedef struct{
+    PyObject ob_base;
+    PyObject *start, *stop, *step;
+  } PySliceObject;
+
+  typedef struct{
+    PyVarObject ob_base;
+    PyObject **ob_item;
+    Py_ssize_t allocated;
+  } PyListObject;
+
+The above definitions of PyObject_HEAD is normative, so extension
+authors MAY either use the macro, or put the ob_base field explicitly
+into their structs.
+
+As a convention, the base field SHOULD be called ob_base. However, all
+accesses to ob_refcnt and ob_type MUST cast the object pointer to
+PyObject* (unless the pointer is already known to have that type), and
+SHOULD use the respective accessor macros. To simplify access to
+ob_type, a macro::
+
+  #define Py_Type(o) (((PyObject*)o)->ob_type)
+
+is added.
+
+Compatibility with Python 2.6
+=============================
+
+To support modules that compile with both Python 2.6 and Python 3.0,
+the Py_Type macro is added to Python 2.6. The macros Py_INCREF
+and Py_DECREF will be changed to cast their argument to PyObject\*,
+so that module authors can also explicitly declare the ob_base
+field in modules designed for Python 2.6. 
+
+Copyright
+=========
+
+This document has been placed in the public domain.
+
+
+
+..
+   Local Variables:
+   mode: indented-text
+   indent-tabs-mode: nil
+   sentence-end-double-space: t
+   fill-column: 70
+   coding: utf-8
+   End:


More information about the Python-checkins mailing list