From 72b143ac4b8f58df01ad0c371eed5646d26850d9 Mon Sep 17 00:00:00 2001 From: aashutosh-sahni <162117475+aashutosh-sahni@users.noreply.github.com> Date: Mon, 4 May 2026 19:47:51 +0530 Subject: [PATCH 1/2] Fix C function names conflicting with ISO C alternative tokens Rename and/or/xor/difference to bitset_and/bitset_or/bitset_xor/bitset_difference. These names are ISO C95 alternative operator tokens (), and Ruby 2.7+ headers pull in that header, causing the preprocessor to replace the function names with operators. Result: 'undefined symbol: and' at runtime. Ruby method aliases ("and", "or", "xor") are unchanged -- only the internal C function names and their pointer references are renamed. --- ext/bitset/bitset.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/bitset/bitset.c b/ext/bitset/bitset.c index 4c63d86..6d19c9e 100644 --- a/ext/bitset/bitset.c +++ b/ext/bitset/bitset.c @@ -556,10 +556,10 @@ static VALUE rb_bitset_equal(VALUE self, VALUE other) { } typedef uint64_t (*bitwise_op)(uint64_t, uint64_t); -inline uint64_t and(uint64_t a, uint64_t b) { return a & b; } -inline uint64_t or(uint64_t a, uint64_t b) { return a | b; } -inline uint64_t xor(uint64_t a, uint64_t b) { return a ^ b; } -inline uint64_t difference(uint64_t a, uint64_t b) { return a & ~b; } +inline uint64_t bitset_and(uint64_t a, uint64_t b) { return a & b; } +inline uint64_t bitset_or(uint64_t a, uint64_t b) { return a | b; } +inline uint64_t bitset_xor(uint64_t a, uint64_t b) { return a ^ b; } +inline uint64_t bitset_difference(uint64_t a, uint64_t b) { return a & ~b; } static VALUE mutable(VALUE self, VALUE other, bitwise_op operator) { Bitset * bs = get_bitset(self); @@ -578,19 +578,19 @@ static VALUE mutable(VALUE self, VALUE other, bitwise_op operator) { } static VALUE rb_bitset_union_mutable(VALUE self, VALUE other) { - return mutable(self, other, &or); + return mutable(self, other, &bitset_or); } static VALUE rb_bitset_intersect_mutable(VALUE self, VALUE other) { - return mutable(self, other, &and); + return mutable(self, other, &bitset_and); } static VALUE rb_bitset_xor_mutable(VALUE self, VALUE other) { - return mutable(self, other, &xor); + return mutable(self, other, &bitset_xor); } static VALUE rb_bitset_difference_mutable(VALUE self, VALUE other) { - return mutable(self, other, &difference); + return mutable(self, other, &bitset_difference); } static VALUE rb_bitset_reset(VALUE self) { From b95d1c420d799d5f8902ca8031bde73058e54683 Mon Sep 17 00:00:00 2001 From: aashutosh-sahni <162117475+aashutosh-sahni@users.noreply.github.com> Date: Mon, 4 May 2026 22:13:27 +0530 Subject: [PATCH 2/2] Use static linkage for bitset helper functions inline alone does not guarantee symbol emission in C99 -- the compiler may inline at call sites and omit the standalone symbol. When the code takes function pointers (&bitset_or etc), the linker fails with 'undefined symbol: bitset_or'. Change to static to ensure symbols are always available in the translation unit. --- ext/bitset/bitset.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ext/bitset/bitset.c b/ext/bitset/bitset.c index 6d19c9e..9fd1cbb 100644 --- a/ext/bitset/bitset.c +++ b/ext/bitset/bitset.c @@ -556,10 +556,10 @@ static VALUE rb_bitset_equal(VALUE self, VALUE other) { } typedef uint64_t (*bitwise_op)(uint64_t, uint64_t); -inline uint64_t bitset_and(uint64_t a, uint64_t b) { return a & b; } -inline uint64_t bitset_or(uint64_t a, uint64_t b) { return a | b; } -inline uint64_t bitset_xor(uint64_t a, uint64_t b) { return a ^ b; } -inline uint64_t bitset_difference(uint64_t a, uint64_t b) { return a & ~b; } +static uint64_t bitset_and(uint64_t a, uint64_t b) { return a & b; } +static uint64_t bitset_or(uint64_t a, uint64_t b) { return a | b; } +static uint64_t bitset_xor(uint64_t a, uint64_t b) { return a ^ b; } +static uint64_t bitset_difference(uint64_t a, uint64_t b) { return a & ~b; } static VALUE mutable(VALUE self, VALUE other, bitwise_op operator) { Bitset * bs = get_bitset(self);