Skip to content

GH-49841: [C++] Fix macOS 12.3 SDK build by using __cpp_lib_int_pow2 - #50998

Open
1fanwang wants to merge 2 commits into
apache:mainfrom
1fanwang:gh-49841-int-pow2-guard
Open

1fanwang wants to merge 2 commits into
apache:mainfrom
1fanwang:gh-49841-int-pow2-guard

Conversation

@1fanwang

@1fanwang 1fanwang commented Aug 25, 2026 •

Copy link
Copy Markdown
Contributor

Rationale for this change

Building Arrow against the macOS 12.3 SDK, which Xcode 13.4.1 ships (https://developer.apple.com/documentation/xcode-release-notes/xcode-13_4_1-release-notes), fails with this error:

error: no member named 'log2p1' in namespace 'std'

The helpers BitWidth and HasSingleBit fall back to the older names std::log2p1 and std::ispow2 on Apple clang whenever __cpp_lib_bitops is undefined. That SDK has std::bit_width but leaves the macro undefined, so the helpers pick names that do not exist there.

Closes #49841.

The macro that goes with std::bit_width and std::has_single_bit is __cpp_lib_int_pow2, as listed at https://en.cppreference.com/cpp/numeric/bit_width. The libc++ headers for 12.0.1 (https://github.com/llvm/llvm-project/blob/fed41342a82f5a3a9201819a82bf7a48313e296b/libcxx/include/version) and 13.0.1 (https://github.com/llvm/llvm-project/blob/75e33f71c2dae584b13a7d1186ae0a038ba98838/libcxx/include/version) comment out __cpp_lib_bitops and define __cpp_lib_int_pow2 as 202002L. The 11.1.0 header (https://github.com/llvm/llvm-project/blob/1fdec59bffc11ae37eb51a1b9869f0696bfd5312/libcxx/include/version) defines neither, so an SDK from that generation keeps using the older names.

What changes are included in this PR?

The guards in BitWidth and HasSingleBit, added in #53946, now test __cpp_lib_int_pow2 instead of __cpp_lib_bitops, and the comment above BitWidth says why. Other compilers are not affected.

Are these changes tested?

Testing Done

I used Apple clang 21.0.0 with the macOS 27.0 SDK on an arm64 Mac. No macOS 11.3 or 12.3 SDK is available there, so the probes undefine the feature macros those SDKs leave undefined. They show which branch of the header each macro combination selects, not a build against the real SDK headers. The header needs only the source include path, and every command ran from the repository root, first on main at d9a0ab4 and then on this branch.

The first probe uses the macro combination from the report, with __cpp_lib_bitops undefined and __cpp_lib_int_pow2 defined:

printf '#include <bit>\n#undef __cpp_lib_bitops\n#include "arrow/util/bit_util.h"\n' |
  clang++ -std=c++20 -I cpp/src -fsyntax-only -x c++ - && echo "compiled successfully"

Output on main:

In file included from <stdin>:3:
cpp/src/arrow/util/bit_util.h:151:32: error: no member named 'log2p1' in namespace 'std'
  151 |   return static_cast<int>(std::log2p1(x));
      |                                ^~~~~~
cpp/src/arrow/util/bit_util.h:148:15: error: no return statement in constexpr function
  148 | constexpr int BitWidth(T x) noexcept {
      |               ^
cpp/src/arrow/util/bit_util.h:164:15: error: no member named 'ispow2' in namespace 'std'
  164 |   return std::ispow2(x);
      |               ^~~~~~
cpp/src/arrow/util/bit_util.h:161:16: error: no return statement in constexpr function
  161 | constexpr bool HasSingleBit(T x) noexcept {
      |                ^
cpp/src/arrow/util/bit_util.h:171:45: error: no matching function for call to 'BitWidth'
  171 | static inline int Log2(uint64_t x) { return BitWidth(x - 1); }
      |                                             ^~~~~~~~
cpp/src/arrow/util/bit_util.h:148:15: note: candidate template ignored: substitution failure [with T = uint64_t]
  148 | constexpr int BitWidth(T x) noexcept {
      |               ^
5 errors generated.

Output on this branch:

compiled successfully

The second probe shows which names each macro combination selects. This SDK has no std::log2p1 or std::ispow2, so routing_probe.cc defines placeholders for them. A result of 3 and 1 means the standard names ran, and -1 and 0 means the placeholders ran. The macOS 11.3 combination should reach the older names on both sides.

for cfg in "as shipped:" "macOS 12:-DSIMULATE_NO_BITOPS" "macOS 11.3:-DSIMULATE_NO_BITOPS -DSIMULATE_NO_INT_POW2"; do
  clang++ -std=c++20 -I cpp/src ${cfg#*:} routing_probe.cc -o routing_probe && printf '%s: ' "${cfg%%:*}" && ./routing_probe
done

Output on main:

as shipped: BitWidth(5u) = 3, HasSingleBit(8u) = 1
macOS 12: BitWidth(5u) = -1, HasSingleBit(8u) = 0
macOS 11.3: BitWidth(5u) = -1, HasSingleBit(8u) = 0

Output on this branch:

as shipped: BitWidth(5u) = 3, HasSingleBit(8u) = 1
macOS 12: BitWidth(5u) = 3, HasSingleBit(8u) = 1
macOS 11.3: BitWidth(5u) = -1, HasSingleBit(8u) = 0
Reproducer source: routing_probe.cc
#include <bit>

#ifdef SIMULATE_NO_BITOPS
#undef __cpp_lib_bitops
#endif
#ifdef SIMULATE_NO_INT_POW2
#undef __cpp_lib_int_pow2
#endif

// Stand-ins for the names the macOS 11.3 libc++ has instead of bit_width and
// has_single_bit. Their results differ from the standard functions on purpose,
// so the output shows which branch of bit_util.h was compiled.
namespace std {
template <class T>
constexpr int log2p1(T) noexcept {
  return -1;
}
template <class T>
constexpr bool ispow2(T) noexcept {
  return false;
}
}  // namespace std

#include <cstdio>

#include "arrow/util/bit_util.h"

int main() {
  std::printf("BitWidth(5u) = %d, HasSingleBit(8u) = %d\n",
              arrow::bit_util::BitWidth(5u), arrow::bit_util::HasSingleBit(8u));
  return 0;
}

The existing bit_util_test needs a full Arrow build and was not run here.

Are there any user-facing changes?

Arrow builds against the macOS 12.3 SDK again. Builds against the macOS 11.3 SDK that CRAN uses, against newer SDKs and with other compilers take the same path as before. There are no public API changes.

Was AI used for this PR?

In accordance to the AI generation guidelines, please disclose below whether and how AI was used in this PR.

PR code and description written by:

  • Human
  • AI

Reviewed before submission by:

  • Human
  • AI
  • Not reviewed

Copilot AI lite review requested due to automatic review settings August 25, 2026 17:07
@1fanwang
1fanwang requested review from pitrou and wgtmac as code owners August 25, 2026 17:07
@github-actions github-actions Bot added the awaiting review Awaiting review label Aug 25, 2026
@github-actions

Copy link
Copy Markdown

⚠️ GitHub issue #49841 has been automatically assigned in GitHub to PR creator.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes Arrow C++ builds against the macOS 12.3 SDK by switching the Apple-clang-specific workaround selector from __cpp_lib_bitops to the correct feature-test macro __cpp_lib_int_pow2, which matches the availability of std::bit_width / std::has_single_bit (and avoids incorrectly selecting the std::log2p1 fallback where it no longer exists).

Changes:

  • Update preprocessor guards at five call sites to use __cpp_lib_int_pow2 instead of __cpp_lib_bitops.
  • Add brief explanatory comments indicating the correct feature-test macro for std::bit_width / std::has_single_bit.
  • Keep all fallback branches and Apple-clang gating (__apple_build_version__) unchanged.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
cpp/src/parquet/encoder.cc Uses __cpp_lib_int_pow2 to correctly choose between std::log2p1 and std::bit_width on Apple clang + varying SDKs.
cpp/src/parquet/chunker_internal.cc Fixes the SDK-dependent selection for computing target_bits to avoid selecting missing std::log2p1.
cpp/src/arrow/util/rle_encoding_test.cc Aligns the test’s feature selection with the correct macro so it matches the production behavior across SDKs.
cpp/src/arrow/util/bit_util.h Fixes the Log2 helper’s Apple-clang workaround guard to correctly detect std::bit_width availability.
cpp/src/arrow/util/align_util.h Corrects the guard for std::has_single_bit selection to use __cpp_lib_int_pow2.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Copilot AI review requested due to automatic review settings September 8, 2026 18:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The changes are narrowly scoped to correcting the feature-test macro used for <bit> APIs on Apple SDKs and match the stated build failure and resolution without introducing behavioral changes beyond the intended conditional selection.

Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@github-actions

Copy link
Copy Markdown

⚠️ GitHub issue #49841 has been automatically assigned in GitHub to PR creator.

@1fanwang
1fanwang requested a review from HuaHuaY as a code owner September 22, 2026 02:12
Copilot AI review requested due to automatic review settings September 22, 2026 02:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

All reviewed changes address the SDK compatibility issue with no unresolved blocking findings.

Review effort: Lite
Findings: None

@1fanwang
1fanwang force-pushed the gh-49841-int-pow2-guard branch from 535e955 to fa11bb2 Compare September 24, 2026 06:28
Copilot AI review requested due to automatic review settings September 24, 2026 06:28
@github-actions

Copy link
Copy Markdown

⚠️ GitHub issue #49841 has been automatically assigned in GitHub to PR creator.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

No unresolved blocking issues were identified.

Review effort: Lite
Findings: None

…_pow2

The macOS 12.3 SDK build failed with "no member named 'log2p1' in
namespace 'std'".

The Apple clang workaround selects std::log2p1 when __cpp_lib_bitops
is undefined, but that macro covers popcount and friends, not
std::bit_width. Use __cpp_lib_int_pow2, which covers std::bit_width
and std::has_single_bit and is undefined on 11.3, defined on 12.3.

Signed-off-by: 1fanwang <1fannnw@gmail.com>
@1fanwang
1fanwang force-pushed the gh-49841-int-pow2-guard branch from fa11bb2 to d0eb576 Compare September 25, 2026 20:51
Copilot AI review requested due to automatic review settings September 25, 2026 20:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

No unresolved review issues were identified.

Review effort: Lite
Findings: None

@github-actions

Copy link
Copy Markdown

⚠️ GitHub issue #49841 has been automatically assigned in GitHub to PR creator.

…w2-guard

The BitWidth and HasSingleBit helpers added in
apache#53946 replaced four of the five guard
sites, so only the two guards in bit_util.h still need the new macro.

Signed-off-by: 1fanwang <1fannnw@gmail.com>
@github-actions

github-actions Bot commented Nov 1, 2026

Copy link
Copy Markdown

⚠️ GitHub issue #49841 has been automatically assigned in GitHub to PR creator.

Copilot AI lite review requested due to automatic review settings November 1, 2026 06:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Regression coverage is missing for the macOS 12 and 11.3 compatibility macro combinations in both helpers, so the prior build failure could be reintroduced without the current tests detecting it.

1 open issue

Review effort: Lite

constexpr int BitWidth(T x) noexcept {
static_assert(std::is_unsigned_v<T>, "BitWidth requires an unsigned integer type");
#if defined(__apple_build_version__) && !defined(__cpp_lib_bitops)
#if defined(__apple_build_version__) && !defined(__cpp_lib_int_pow2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[C++] error: no member named 'log2p1' in namespace 'std'

2 participants