常に署名されていません

2026/07/09 4:35

常に署名されていません

RSS: https://news.ycombinator.com/rss

要約

日本語訳:

原文は強力ですが、流れを改善し、著者の C/C++ の振る舞いに対する見解と業界の慣行との区別をさらに明確にするために、若干微調整する余地があります。

改善された要約:

この文章では、符号付き整数演算が多くの場合危険かつ不必要であり、メモリ安全性と簡略化されたロジックを実現するためのより優れた代替手段として無符号型への移行を提唱しています。著者は、大多数の整数は負値を表さないにもかかわらず、それを符号付きとして扱うことは、有効な文脈において不可能な状態を暗示することで「null ポインタ」に似た複雑性を導入すると主張します。特に重要なのは、符号付き演算が頻繁に未定義動作(例:

INT_MIN / -1
)やシステムパニックを引き起こすのに対し、無符号演算は減算による下のフロー(underflow)でも予測可能であり、巻き戻し最適化のために正しくコンパイルされる点です。Google C++ スタイルガイドのような業界ガイドは無符号型の使用を推奨していませんが、著者はこの助言が不安全な慣行を促進すると見なしています。その代わりに、開発者には Rust、Go、または Odin に見られるパターンを採用し、安全な逆方向反復を実現し、エラーの多いキャストを排除し、複雑なチェックなしに異なる場合を安全に処理すべきだと主張します。無符号演算を採用することで、防御的な範囲アサーションの必要性を取り払い、明確な値の範囲を通じて激しいコンパイラ最適化を可能にし、符号付きアンダーフローや無効な配列インデックスに関連する脆弱性を大幅に減少させることができます。

本文

すべてを無符号整数へ:有符号整数がしばしば問題となる理由

著者: デール・ワイラー
最終更新日: 2022 年 1 月 1 日

概要

プログラム内の大多数の整数は実際には負の値を表せず、配列のインデックスやループ反復回数などでよく扱われる。したがって、有符号整数よりも無符号整数の利用頻度を高めることが望ましい。しかし現状では排他的に有符号整数を使用するという誤った選択が多く見られる。

本記事は主に C および C++ を焦点とするが、Go、Rust、Odin といった他の言語の例も示し、演算そのものの性質から議論を展開する。


無符号整数への反対意見に対する反論

セーフティに関する議論

  • 最も一般的な批判は「無符号整数のアンダフロー(下回し)が溢れ(オーバーフロー)よりも容易で危険である」という点にある。
  • しかし、これは誤った安堵を与える批判であり、不安定なコードを継続する方向を促す
  • 適切な慣用句を使用すれば、これらの問題は容易に回避可能である。

逆方向ループに関する議論

有符号整数に変換した誘惑から避けるための正しいアプローチは以下の通りである。

❌ 危険な有符号変換(NG)

// 幅の狭くなる変換を行い、正当な警告を無視するキャストを行っている
for (int64_t i = int64_t(size) - 1; i >= 0; i--) { 
    // ...
}
  • 問題:
    i >= 0x7fffffffffffffff
    のような値が入力されると、C/C++ では未定義の行動(Undefined Behavior)となり、ほぼ確実に攻撃対象となる。
  • 批判の誤り: 「そのような値は病的である」という議論自体が誤りで、有符号整数を使用すれば無条件にアンダフローを呼び出し、未定義の行動を引き起こす

✅ 正しいアプローチ(NG)

// 無符号アンダフローが良定义的であることを認識し、巻戻し演算を利用する
for (size_t i = size - 1; i < size; i--) { 
    // ...
}
  • 仕組み:
    size - 1
    から始め、ゼロになった時点でアンダフローにより最大値に巻き戻る。その値は
    size
    より大きいため
    i < size
    が偽となりループが終了する。

Rust の例

Rust ではデバッグビルドでアンダフローをトラップ表現(trap representation)にする検討があるが、巻戻し振る舞いをクリーンな構文で安全に実現できるのが

[0..size).rev()
などである。

// 無符号アンダフローをクリーンに処理
for i in (0..size).rev() { 
    // ...
}
  • キャスト不要
  • 「病的」な入力を正しく動作させる(
    [0, 0xffffffffffffffff)
    の範囲をカバー)
  • size == 0
    でも機能する(ループ進入しないため)

2 つの数の差が負になる可能性があるという議論

$$ \Delta = x - y $$

  • 批判:
    y > x
    の場合に無符号アンダフローが発生するため危険とされる。
  • 反論: どちらのケースでも「有符号アンダフローを招く値」が存在する。C/C++ では有符号アンダフローが未定義であるため、無条件にエラーとなる。
  • 解決策: 安全な差の計算は有符号で非常に難しい(
    INT_MAX - INT_MIN
    でさえ誤りとなる)。

❌ 有符号での安全な実装(複雑)

if ((y > 0 && x < INT_MIN + y) || (y < 0 && x > INT_MAX + y)) {
    // エラー処理
} else {
    delta = abs(x - y);
}

✅ 無符号での実装(簡単で安全)

delta = max(x, y) - min(x, y);
// 常に安全に絶対値の差を与える
  • 読みやすく、式自体が自己説明的であるため変数名の「delta」も不要。

符号付き演算によるインデックス計算の方が安全であるという議論

複雑な式でのインデックス計算において有符号を使用する主張は誤りであり、有符号整数著しく悪化する傾向がある

区間の中間点計算例

バイナリ検索やマージソートなどで一般的に見られる

(low + high) / 2
は危険である。

int mid = (low + high) / 2; // 合計が INT_MAX を超えると負へオーバーフロー
  • 有符号の解決策
    low + (high - low) / 2
    :
    low=INT_MIN, high=INT_MAX
    の場合依然として失敗。
  • 無符号の場合
    (low + high) / 2
    :
    low=0x80000000, high=0x80000002
    で機能せず、正しい値
    0x80000001
    が得られない。

結論

  • 有符号: メモリ安全性の問題を引き起こす(無効なインデックス)。
  • 無符号: インデックスが間違っても有界の値であり、論理的バグに留まる。

✅ 正しい方法:巻戻しに対してマスク付き加算を使用

C++ の

std::midpoint
が行うように、すべての変数を無符号に変換する。

template<typename T> 
T midpoint(T x, T y) {
    using U = std::make_unsigned<T>; // 型 T の無符号バージョン
    const auto digits = std::numeric_limits<T>::digits;
    
    U shift = digits - 1;
    U difference = (U)x - (U)y;
    U sign = y < x;
    // mask付き加算のロジック
    U half = (difference / 2) + (sign << shift) + (sign & difference); 
    return (T)(x + half);
}

無符号乗算が溢れる可能性があるという議論

malloc(sizeof(Object) * n)
が溢ると、十分でないメモリを割り当ててしまう。

  • 有符号の場合: 負の値は
    size_t
    にキャストされて約 4 GiB となり、静かにメモリ漏れを生じるリスクがある。

✅ より良い解決策

C++:

std::make_unique<Object[]>(n); // 安全な割り当て
// または
auto arr = std::make_unique<Object[]>(n);

Go:

arr := make([]Object, n) // 自動オーバーフロー検出
arr := make([]Object, n, m) // コンストラクターによる安全な実装

チェックの簡易化

x * y
が溢れるかチェックするテストはシンプルである:

if (x != 0 && y > ((T)-1) / x) { 
    // オーバーフロー発生((T)-1 は UINT_MAX に相当)
}

センチネル値

  • 有符号整数での慣行: 「負の値=エラー」をエンコードする。これは字句的なカテゴリー誤りで、ひどいプログラミング実践である。

✅ 無符号整数でも安全な代替手段

  1. 結果用のアウトパラメータ
    if (uint result; connect(&result)) { }
    
  2. タプルまたはペアの返却
    tuple<bool, uint> result = connect();
    if (get<0>(result)) { ... }
    
  3. オプション型(Rust)
    match connect() {
        Some(u32) => // ...
        None      => // エラー
    }
    
  4. enum で全域を定義
    enum class ConnectionStatus : unsigned {
        Connected,
        NoRouteToHost,
        Disconnected,
        TimedOut
    };
    if (status == ConnectionStatus::Connected) { ... }
    
  5. 複数の返却値(Go / Odin)
    status, err := connect()
    if err != nil { ... }
    

デフォルトであるという議論

  • C/C++ は
    int
    を有符号と定義し、これがデフォルトになった。しかしこれは多くのデフォルトが悪かったことに合意されている。
  • プログラミング言語のデフォルトは例外ではなくルールと一致すべきである。

有符号整数を巻戻しするように定義したらどうでしょうか?

Go/Rust/Odin などで行われる「有符号巻戻し」への安全利用は限界がある。

  • 問題: すべての配列アクセスで境界チェックが必要になり、実行時コストが発生する。維持が困難なためである。
  • 未定義の行動リスト(LLVM ベース言語共通):
    • x / 0
    • INT_MIN / -1
    • INT_MAX % -1
    • INT_MAX - INT_MIN
      これらは Go/Rust/Odin でさえ無効な結果を生じる。

トラップ表現について

Rust などではアンダフローを「パニック(トラップ)」とするアプローチもあるが不十分である。

  • 理由: コバレッジが不十分で、非自明なプログラムではテストしきれない。
  • サービス可用性: パニックはサービス拒否攻撃に対して脆弱であり好ましくない。
  • C/C++ vs Rust: C/C++ は無符号を巻戻し(安全)、有符号をトラップする。一方 Rust は逆(有符号も無符号も条件付き)となり、整数演算においてのみ有効なコードが得られる

あなたの反論は病的入力についてである

  • 「悪意のある入力か」と判断するのは時間見積もりと同等の精度しかない。要件は常に変化する。
  • 過去の事例(例:qmail の CVE)は、有符号整数演算を避け、病的入力を直接的に扱うことで防ぐことが可能であることを示す。

無符号整数のための議論

プログラム内の大多数の整数は決して負の値を表現しない

  • 型による指示: 無符号整数は「負ではない量」を示すのに適した型である(サイズ付き整数型のよう)。
  • 統計的根拠: Intel の研究によると、デスクトップ x86 Windows システム全体の整数のうちわずか 3% だけが負の値を表している。
    • その場合でも、コードベースの約97% は有符号であるべきではない

コンパイラ診断は無符号にとって良いが、全体としては悪

  • 混在した使用でコンパイル警告が出ることがあるが、これらは助けることを意図しているが、能動的に悪意的な挙動を示す(沈黙させることで危険なキャストを許容)。
  • 色の例え:
    • 有符号 =
    • 無符号 =
    • 例外は負の値のみ。ルールは「すべてが同じ符号性を共有する」方が適切であるため、全てを青色(無符号)にするのが最適

オーバーフローおよびアンダフローをチェックするのが容易で安全である

  • 有符号の問題: C/C++ では未定義行動となるため、チェックコード(
    if (x + y < x)
    など)はコンパイルエラーに繋がる。
  • 無符号の解決策: 完全に安全かつ適切。
    • 例外:Go/Rust/Odin の有符号巻戻し定義では
      INT_MIN
      および
      INT_MAX
      で問題が発生する可能性がある(LLVM の限界)。
    • 冗長なチェック例(覚える必要のない怪物コード):
    if ((b > 0 && a > INT_MAX - b) || (b < 0 && a < INT_MIN - b)) 
    

コードは単純で速くなる

  • 境界チェックの削減: 負になることがないため、
    NULL
    チェック(有符号の NULL ポインタに相当)のようなテストが不要になる。
  • 最適化の利点: コンパイラはオーバーフローがないことを仮定してより高度な最適化を行うことができる。
    • 値範囲分析:
      b = a + 2
      b > a
      を確立し、コンパイラに有効な手がかりを与える。

それは実際に機能します

  • 有符号整数を避けるとコードが容易でクリーンになり、強固になる
  • 注意: 既存のコードベースへ導入することはお勧めしない(静かなバグの原因となる可能性がある)。
  • 推奨: 新しいプロジェクトではまず無符号整数を使用することを試してみる

同じ日のほかのニュース

一覧に戻る →

2026/07/09 5:05

FAANGシミュレーター

## Japanese Translation: 「FAANG™ Life Simulator featuring MILTON」は、エントリーレベルのテックワーカーが直面する激しいプレッシャーを批判的に検証する風刺モバイルゲームです。このシミュレーションでは、**1 回のタップは人生の 1 四半期を表し**、**1 つのグリッドマスは 1 ヶ年を表す**ことで、プレイヤーには急速な加齢と変動するメトリクスを管理させながら、過酷な現実を目撃させる仕組みとなっています。初期状態として Milton は 22 歳(Q1)、パフォーマンススコアが 50、バーンアウトが 10 の状態で始まり、高給与(年額 19 万ドル)と金銭的自由の欠如(退職永久資金 0%)、そして資産総額 0 が同時に存在する厳しい現実を描き出します。プレイヤーがこれらの制約の中で動き回りながら、企業が 0% のトラクションを示す中で、特定のアクションによって定義された明確な複数のエンディングへと至ります:その行為とは、**「Form HR-1099-RAT」の記入**、**「Exit Interview」への参加**、そして**「GO HOME」画面の表示**です。シミュレーション終了後、プレイヤーはその結果を 𝕏(X)に投稿し、自らの架空のキャリアの終焉をデジタル記録として残すことができます。最終的に、このプロジェクトは業界全体の課題である従業員の福祉、定着率の難しさ、一流テクノロジー企業で働く際の隠れたコストなどについて鋭い評論を行い、官方的な提携はないまま、現状の高い成長を志向する専門職モデルの持続可能性に疑問を投げかける魅力的な体験へと抽象的な企業データを転換します。

2026/07/09 0:19

Chatto はオープンソースになりました

## Japanese Translation: Chatto は、セルフホスト用に設計された新たにリリースされたオープンソースのグループチャットおよびチームチャットアプリケーションです。ユーザーは、`brew install chattocorp/tap/chatto` で Homebrew を使用して Linux (x86_64/ARM64)、macOS、Windows 上ですぐに試すことができます。その後、`chatto init` と `chatto run` を実行します。その核心的な強みは、コンパクトなパフォーマンス、堅牢なプライバシー、完全なデータ保護です:すべてのデータは静態で暗号化され、アカウント削除時にユーザー固有の鍵が完全に「破棄」され、データ痕跡は残りません。連邦システムとは異なり、Chatto はサードパーティの追跡がない単一サーバーのコミュニティモデルを運用し、クライアントは同時に複数のサーバーに直接接続できます。内蔵された音声通話、ビデオ通話、画面共有はすべてエンドツーエンドで暗号化され、インフラストラクチャのキャパシティに応じてスケーリングします。現在、production 使用のためにバージョン 0.4 が安定しており、Chatto は広告やベンダーロックインを回避しています。有料の「Chatto Cloud」サービスが間もなくヨーロッパ所有のインフラ上で開始され、広告なしでロックインなく安全なホスティングを提供し、自動スケーリング、夜間のバックアップ、ダウンタイムなしのアップグレード、セルフホストされたサーバーとの完全互換性を提供します。追加のリージョンは 2027 年初頭に予定されています。バージョン 0.5 は安全性機能、コンテンツモデレーション、クライアントの改良に焦点を当て、予想される 1.0.0 リリースに向けて進みます(注:新しいバージョンがロールアウトするにつれて破壊的変更が発生する可能性があります)。コミュニティサポートは Chatto HQ の専用の #self-hosting チャンネルで利用でき、リリースおよび早期 Cloud ベータへのアクセスに関する更新のために低ボリュームのニュースレター(〜1 封/月)を購読することもできます。この安全かつ広告なしのプラットフォームは、現代のマルチメディア機能を損なうことなくユーザーの主権を優先します。 ## Text to translate: Chatto is a newly released open-source group and team chat application designed for self-hosting. Users can immediately try it on Linux (x86_64/ARM64), macOS, or Windows via Homebrew with `brew install chattocorp/tap/chatto`, then run `chatto init` and `chatto run`. Its core strengths are compact performance, robust privacy, and full data protection: all data is encrypted at rest and per-user keys are completely "shredded" upon account deletion, leaving no data trails. Unlike federated systems, Chatto operates on a single-server community model with no third-party tracking; clients can connect directly to multiple servers simultaneously. Built-in voice, video calls, and screen-sharing are fully end-to-end encrypted and scale with infrastructure capacity. Currently stable at version 0.4 for production use, Chatto avoids ads and vendor lock-in. A paid "Chatto Cloud" service is launching soon on European-owned infrastructure, offering secure hosting without ads or lock-in, automatic scaling, nightly backups, zero-downtime upgrades, and full compatibility with self-hosted servers; additional regions are expected in early 2027. Version 0.5 will focus on safety features, content moderation, and client polishing, leading to the anticipated 1.0.0 release within 6–12 months (note: breaking changes may occur as new versions roll out). Community support is available at Chatto HQ via a dedicated #self-hosting channel, and users can subscribe to a low-volume newsletter (~1 email/month) for updates on releases and early Cloud beta access. This secure, ad-free platform prioritizes user sovereignty without compromising modern multimedia capabilities.

2026/07/09 3:00

Grok 4.5

## Japanese Translation: SpaceXAI は、コーディング、エージェンタスク、複雑な知識業務に特化して Cursor と共同開発された、現時点で最も高度なモデルである Grok 4.5 を発売しました。本モデルは、単一のプロンプトからエンドツーエンドのアプリケーションを構築する(太陽系など細部の模擬を含む)などの強力な能力を示していますが、主要なベンチマークでは 3 位にランクインしています:DeepSWE 1.0 で 62.0%、Terminal Bench 2.1 で 83.3%、SWE Bench Pro では解決率が 64.7% と、GPT-5.5 xhigh および Fable に及ばない結果となっています。本モデルは、数万台の NVIDIA GB300 GPU を使用し、高度なデータ選別技術と、トークンごとの知能に焦点を当てた強化学習戦略を採用することで、同等モデルと比較して約 4.2 倍のトークン効率を達成しています。 Grok 4.5 は、入出力トークンあたりそれぞれ 100 万トークンで 2 米ドルおよび 6 米ドルという高速サービスを提供しており、限定期間中の無料利用オファーも用意されています。現在、Excel リサーチや PowerPoint の図表作成を強化する目的で Grok Build、Cursor、SpaceXAI コンソールに統合されていますが、ヨーロッパ連合では 7 月中旬のローンチまでの間利用できません。

常に署名されていません | そっか~ニュース