Skip to content

C++ extension fails to compile under GCC/libstdc++ (blocks Linux wheels) #7

Description

@sqr00t

Summary

The C++ extension does not compile under GCC + libstdc++ (the Linux/manylinux toolchain). It compiles fine under Apple Clang + libc++ (local macOS dev and the macOS CI runner), which is why the failure only shows up on Linux.

This blocks producing Linux wheels (x86_64 and arm64) and blocks any Linux consumer who builds the published sdist from source.

Root cause

In src/shim.hpp, NumericVector both inherits std::vector<double>'s constructors:

using std::vector<double>::vector;                 // brings in vector(size_type, const value_type&, ...)

and declares its own overlapping constructors:

explicit NumericVector(size_t n) : std::vector<double>(n, 0.0) {}
NumericVector(size_t n, double v) : std::vector<double>(n, v) {}

A call like NumericVector(cols, 0.0) (with cols an int, e.g. shim.hpp:186 and :285) is then ambiguous between the inherited vector(size_type, const value_type&) and the custom NumericVector(size_t, double) — both require the same int → size_t conversion. GCC rejects this per the standard; Clang happens to resolve it.

src/shim.hpp:186:43: error: call of overloaded 'NumericVector(int&, double)' is ambiguous

Confirmed reproducible locally with g++-16 and on the ubuntu-latest CI runner (GCC 13). -fpermissive does not fix it (hard error, not a warning). Casting the argument to size_t does not fix it either (the ambiguity is by-value vs const-ref, both exact matches).

Proposed fix (verified on both Clang and GCC)

Remove the two custom constructors that duplicate the inherited ones, keeping the using declaration:

class NumericVector : public std::vector<double> {
public:
    using std::vector<double>::vector;   // provides (), (n), (n, v), init-list, range, copy, move
    NumericVector(const std::vector<double> &v) : std::vector<double>(v) {}
    // removed: explicit NumericVector(size_t n)     — duplicated inherited ctor
    // removed: NumericVector(size_t n, double v)    — the ambiguous one
    ...
};

All existing NumericVector(...) construction sites ((n, value), (vec), ()) are covered by the inherited constructors; nothing uses brace-init, so this is safe. A minimal repro of this exact change compiles cleanly under both clang++ (libc++) and g++-16 (libstdc++).

Acceptance criteria

  • src/shim.hpp compiles under GCC (Linux) and Clang (macOS).
  • Enable the Linux legs of the publish matrix (remove continue-on-error, switch Linux builds to cibuildwheel/manylinux — see the matrix CI PR).
  • Local uv build on macOS still succeeds and behaviour is unchanged.

Context

Deferred out of the matrix-CI work so that C++ source changes are reviewed separately from CI config. The publish workflow currently builds Linux legs as non-blocking (continue-on-error) until this lands.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions