pd: register the class under the external's own name (fixes Pd recursion / can't-instantiate)#168
Merged
Conversation
Pd finds a single-object external by filename and requires the registered class
symbol to equal that filename. avendish names the file and the setup function
after the CMake C_NAME (@AVND_C_NAME@.pd_*, @AVND_C_NAME@_setup), but the class
was registered under symbol_from_name<T>() = the introspected C++ symbol/
identifier. When those differ (e.g. an addon whose C_NAME is 'smoother' but whose
struct is 'Smoother', or any object without a c_name meta), Pd loads the file,
runs setup, but the class it asked for is never registered -- so its loader
retries and eventually aborts with the abstraction recursion limit. This made
most puara objects impossible to instantiate.
Thread @AVND_C_NAME@ from the setup function into the audio/message metaclass so
class_new() uses exactly the external's name (falling back to the old introspected
name when the metaclass is constructed directly, e.g. in tests).
Verified: an addon with C_NAME 'coolthing' and struct 'Foo' (no c_name meta) now
emits coolthing_setup() -> class_new(gensym("coolthing")) and builds a
coolthing.\* external; previously it registered class 'Foo' and could not be created.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Z4KK2Rays9dTj8J2AJcFZ
jcelerier
force-pushed
the
fix-pd-class-name
branch
from
July 9, 2026 19:40
2e639eb to
7f74ad1
Compare
Every object is built for the golden differential harness (SDK-free, always on), so one static_assert there enforces the name invariant for all back-ends at once, rather than duplicating it per shipping backend: when an object declares an explicit halp_meta(c_name, ...), the avnd_addon_object / avnd_make_* C_NAME must equal it (they name the same external -- the file + class Pd/Max load by). Objects that declare no c_name leave the CMake C_NAME authoritative. Verified across all 224 golden objects. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Z4KK2Rays9dTj8J2AJcFZ
The object declares c_name() == "avnd_sampleaccurate" but was built as C_NAME avnd_sample_accurate_controls, which the golden static_assert rejects. Use the object's declared name. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Z4KK2Rays9dTj8J2AJcFZ
jcelerier
force-pushed
the
fix-pd-class-name
branch
from
July 9, 2026 20:17
17db40d to
66eff6a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Symptom
In Pure Data, most objects of an addon like
score-addon-puaracan't beinstantiated — Pd aborts with its abstraction recursion limit.
Root cause
Pd loads a single-object external by filename and requires the registered
class symbol to equal that filename. avendish names the file and the setup
function after the CMake
C_NAME(<C_NAME>.pd_*,<C_NAME>_setup), but the Pdbinding registered the class under
symbol_from_name<T>()— the introspectedC++ symbol/identifier (
get_static_symbol), notC_NAME.When they differ — e.g. puara ships
C_NAME smootherfor a structSmoother, orany struct without a
c_namemeta (soget_c_name/get_static_symbolfall backto the identifier) — Pd loads
smoother.pd_linux, runssmoother_setup, but theclass it registers is
Smoother. Pd never findssmoother, retries via theloader, and eventually hits the recursion limit. (Max has the same class:
class_new(get_c_name<T>())— see follow-ups.)Fix
Thread
@AVND_C_NAME@from the setup function into the audio/message metaclass soclass_new()uses the external's own name. Falls back to the introspected namewhen the metaclass is constructed directly (tests), so nothing else changes.
Validation
An addon with
C_NAME coolthing/ structFoo(noc_namemeta) now generatescoolthing_setup()→class_new(gensym("coolthing"))and builds acoolthing.*external. Before, it registered class
Fooand[coolthing]could not be created.Follow-ups (not in this PR)
class_new(get_c_name<T>())has the same flaw — it should use@AVND_C_NAME@too, or it breaks wheneverC_NAME != get_c_name.c_name(
= get_c_name<T>), so they still reference the introspected name rather thanthe shipped
C_NAME. Making the dump'sc_nameauthoritative (@AVND_C_NAME@)would fix the demo object box in every backend's help patch.
🤖 Generated with Claude Code
https://claude.ai/code/session_014Z4KK2Rays9dTj8J2AJcFZ