GN⁺ 5시간전 | parent | ★ favorite | on: GCC 16이 출시됨(gcc.gnu.org)
Hacker News 의견들
  • 사람들이 채택해야 하지만 실제로는 잘 안 쓰일 것 같은 구현 기능으로 P2590R2 Explicit lifetime management를 짚고 싶음
    이건 std::start_lifetime_as를 위한 것으로, 포인터를 구조화된 타입으로 type-pun할 때 UB가 아닌 방식
    외부 I/O 버퍼를 다루는 거의 모든 zero-copy 코드는 대략 reinterpret_cast(buffer.get())처럼 생겼고 이는 undefined behavior인데, 이제 reinterpret_caststart_lifetime_as로 바꾸면 더 이상 나쁜 짓이 아님
    https://en.cppreference.com/cpp/memory/start_lifetime_as

    • 이미 합법적으로 할 수 있는 방법이 있었고, 모두 그걸 쓰고 있어야 했음. 포인터를 no-op memmove로 laundering하는 방식임
      여기서 reinterpret_cast를 쓰는 건 버그임
      start_lifetime_as는 메모리 laundering 주문에 깔끔한 표준 이름을 붙이는 것 말고도 하나를 더 해줌. 의미상 메모리를 건드리지 않는 반면 no-op memmove는 본질적으로 메모리를 건드림. 실제로는 컴파일러가 memmove가 no-op임을 보고 최적화할 수 있어서 큰 차이는 적음
    • alignment 제약을 무시한다면 read 구현에 따라 다름. 컴파일러 입장에서 완전히 opaque하다면, 커널이나 네트워크 카드 같은 것이 실제로 그 버퍼 안에 Foo를 구성하는 셈이라 cast가 완전히 정당해짐
      start_lifetime_as는 버퍼 lifetime이 컴파일러에 투명해서 aliasing 가정을 망칠 수 있을 때 유용함
    • cppreference 설명이 좀 의심스러움
      T가 완전한 새 객체이고 그 안에 subobject들이 있으며, 그중 하나가 U 타입이라는 뜻으로 보임. Ubit_cast처럼 초기화되는데, 아마 해당 주소에 이미 있는 비트에서 cast한다는 뜻이었을 것 같음. 그런데 obj가 정의 없이 등장하니 올바른 주소에 있는 무언가를 뜻한다고 봐야 할 듯함
      하지만 E가 무엇인지가 애매함. 페이지에는 “E is the lvalue of type U denoting obj”라고 되어 있는데, obj는 아마 char 같은 타입일 것이고 이미 U 타입이었다면 bit_cast가 필요 없었을 것임
    • char 버퍼는 type punning이 허용됨
    • 그 코드는 나쁜 것뿐 아니라 alignment 문제 때문에 올바르지도 않음
  • 방금 찾아보기 전까지 GCC 릴리스 일정이 이렇게 규칙적인 줄 몰랐음: https://gcc.gnu.org/develop.html

    • 큰 프로젝트들은 오래전부터 정기 릴리스로 가고 있음
      90년대까지는 원하는 기능을 모두 넣은 대형 릴리스를 waterfall로 만들 수 있다고 생각했지만, 프로젝트가 커지면 항상 아직 준비 안 된 기능을 작업 중인 사람이 생김. 정기 릴리스를 하면 그래도 고객에게 릴리스를 제공할 수 있음
      이 방식은 준비 여부가 불확실한 개발자에게 불안정 기능을 끄는 토글을 만들도록 강제하고, 현실적으로 그게 최선에 가까움
    • 최근 GCC 메이저 릴리스는 꽤 규칙적이었고, Fedora의 봄 릴리스와도 비슷하며 더 큰 리듬 안에 맞아 보임. 힌트는 Red Hat
    • Cygnus 사람들이 프로젝트를 재정비한 뒤로 그렇게 됐음. 지금은 RedHat→IBM으로 이어짐
    • 기억하기로는 GCC가 GPL3 적용을 받은 뒤부터였음
      예전에는 더 느렸고, GCC 2.95의 C++ 버그를 우회하느라 너무 많은 시간을 썼음
      문제가 된 버전을 아직 기억한다는 사실 자체가 많은 걸 말해줌
  • 이미 한동안 써왔음. Debian sid에는 trunk 패키지가 있음
    c++26 reflection이 들어 있어서 reflection으로 마법 같은 일을 좀 하고 있고, ser-des 같은 일부 경우에는 훨씬 낫다
    생태계 안에 LSP 서버만 있으면 좋겠음

    • Debian 12와 13에서 GCC 16 바이너리를 실행할 때 libstd가 문제를 일으키고 있음
  • -fdiagnostics-format=의 이른바 json 포맷은 이번 릴리스에서 제거됐고, GCC에서 machine-readable diagnostics가 필요하면 SARIF를 쓰라고 되어 있음
    그런데 -fdiagnostics-add-output=experimental-html로 diagnostics를 HTML 출력할 수 있게 됐다고도 함
    JSON 출력을 제거하면서 HTML 출력을 추가한 결정의 배경이 궁금함

    • SARIF는 정식 스키마가 있는 JSON처럼 보임. 이전에 출력하던 JSON은 자체 비표준 스키마였던 듯함
  • 초보 질문인데, GCC는 내부에서 LLVM을 어디든 쓰는지, 아니면 자체 code generation과 optimization pipeline을 갖고 있는지 궁금함. LLVM과 비교하면 어떤 수준인지도 궁금함

    • GCC는 LLVM을 쓰지 않음
      LLVM보다 더 많은 target을 지원하고, 대부분의 경우 비슷하거나 더 나은 실행 파일을 생성함
    • 위키피디아식으로 답하면, 이미 나온 것처럼 GCC가 LLVM보다 훨씬 오래됨
      Wikipedia 기준 GCC는 1987년 3월 22일, LLVM 초기 릴리스는 2003년임
      또 큰 차이는 라이선스임. GCC는 GPL, LLVM은 Apache License라서 두 프로젝트가 코드를 공유하지 않음
    • 안 씀
    • 다른 답들의 “아니오!”가 맞지만, 예전에는 GCC에서 LLVM backend를 쓰는 GCC 플러그인이 있었음
      Apple은 GCC에서 LLVM으로 전환하던 시기인 2012년쯤 llvm-gcc를 썼고, 이는 GCC front end와 LLVM back end 조합이었음
      https://dragonegg.llvm.org
    • GCC는 LLVM보다 훨씬 오래됐고, 둘은 코드를 공유하지 않음
  • -Ofast는 아직도 -fno-fast-math를 무시하나?

  • 지난 약 3개월 동안 unstable 소스를 써봤음
    최근 GCC로는 컴파일되지 않지만 예전 GCC로는 잘 되는 프로그램들이 있어서, 현재로서는 전반적으로 gcc 15.x가 나에게 더 잘 맞음
    그래도 3000개 넘는 프로그램을 컴파일한다고 보면 대부분은 잘 되고, 일부만 패치가 필요함. 그런 패치는 LFS/BLFS에서 찾을 수 있는 경우가 많고, 개별 문제를 sed로 고치면 대개 동작함
    그런 문제들이 고쳐졌기를 바람. 우리 모두에게는 안정성과 “그냥 되는 것”이 필요함

    • 그 문제들에 대해 버그 리포트는 올렸나?