Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Interesting, this is a case where GCC and Clang are "dumb" and MSVC does a better job. For code

  #include <cstdlib>
  #include <cstdint>
  #include <utility>
  
  std::pair<int64_t, int64_t> LibDivWithRemainder(int64_t numerator, int64_t denominator) {
    const auto res = std::div(numerator, denominator);
    return std::make_pair(res.quot, res.rem);
  }
  
  std::pair<int64_t, int64_t> ManDivWithRemainder(int64_t numerator, int64_t denominator) {
    const int64_t quot = numerator / denominator;
    const int64_t rem = numerator % denominator;
    return std::make_pair(quot, rem);
  }
GCC (x86-64 trunk @ -O2) produces

  "LibDivWithRemainder(long, long)":
    sub     rsp, 8
    call    "ldiv"
    add     rsp, 8
    ret
  "ManDivWithRemainder(long, long)":
    mov     rax, rdi
    cqo
    idiv    rsi
    ret
Clang (x86-64 @ -O2) produces

  LibDivWithRemainder(long, long):
    jmp     ldiv@PLT
  ManDivWithRemainder(long, long):
    mov     rax, rdi
    mov     rcx, rdi
    or      rcx, rsi
    shr     rcx, 32
    je      .LBB1_1
    cqo
    idiv    rsi
    ret
  .LBB1_1:
    xor     edx, edx
    div     esi
    ret
while MSVC (x64 @ /O2) produces

  mov     rax, rdx
  cdq
  idiv    r8
  mov     QWORD PTR [rcx], rax
  mov     rax, rcx
  mov     QWORD PTR [rcx+8], rdx
  ret     0
for both


Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: