Skip to content

[cppyy] Disallow calling functions with non-const pointer references#21655

Draft
guitargeek wants to merge 1 commit intoroot-project:masterfrom
guitargeek:cppyy_ptr_ref
Draft

[cppyy] Disallow calling functions with non-const pointer references#21655
guitargeek wants to merge 1 commit intoroot-project:masterfrom
guitargeek:cppyy_ptr_ref

Conversation

@guitargeek
Copy link
Contributor

@guitargeek guitargeek commented Mar 22, 2026

Functions taking non-const references to pointers (T*&) allow rebinding the pointer inside the callee. This behavior does not map cleanly to Python, which has no equivalent concept of pointer rebinding.

In cppyy, this can lead to confusing and unintended side effects due to pointer deduplication and proxy identity semantics.

This change explicitly rejects such argument types and raises a TypeError with a clear explanation and suggested alternatives.

Here is an example of previously confusing behavior:

import cppyy

cppyy.cppdef("""

struct MyClass {
   int val = 0;
};

MyClass *staticPtr() {
   static MyClass x;
   x.val = 1;
   return &x;
}

void changePtr(std::string ptr) {
}

void changePtr(MyClass *& ptr) {
   static MyClass y;
   y.val = 2;
   ptr = &y;
}

""")

p1 = cppyy.gbl.staticPtr()
p2 = cppyy.gbl.staticPtr()

cppyy.gbl.changePtr(p2)

print(p1.val)
print(p2.val)

Output:

2
2

Here, it was completely not obvious that changing p2 is changing the p1 pointer.

@github-actions
Copy link

github-actions bot commented Mar 22, 2026

Test Results

    22 files      22 suites   3d 8h 2m 38s ⏱️
 3 832 tests  3 830 ✅ 1 💤 1 ❌
75 650 runs  75 640 ✅ 9 💤 1 ❌

For more details on these failures, see this check.

Results for commit e79d656.

♻️ This comment has been updated with latest results.

Functions taking non-const references to pointers `(T*&)` allow
rebinding the pointer inside the callee. This behavior does not map
cleanly to Python, which has no equivalent concept of pointer rebinding.

In cppyy, this can lead to confusing and unintended side effects due to
pointer deduplication and proxy identity semantics.

This change explicitly rejects such argument types and raises a
`TypeError` with a clear explanation and suggested alternatives.

Here is an example of previously confusing behavior:

```Python
import cppyy

cppyy.cppdef("""

struct MyClass {
   int val = 0;
};

MyClass *staticPtr() {
   static MyClass x;
   x.val = 1;
   return &x;
}

void changePtr(std::string ptr) {
}

void changePtr(MyClass *& ptr) {
   static MyClass y;
   y.val = 2;
   ptr = &y;
}

""")

p1 = cppyy.gbl.staticPtr()
p2 = cppyy.gbl.staticPtr()

cppyy.gbl.changePtr(p2)

print(p1.val)
print(p2.val)
```

Output:
```txt
2
2
```

Here, it was completely not obvious that changing `p2` is changing the
`p1` pointer.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant