共用方式為


警告 C26446

偏好使用 gsl::at() 而不是未核取的下標運算子 (bounds.4)。

C++ 核心指導方針: Bounds.4:請勿使用未檢查 界限的標準程式庫函式和類型。

備註

C++ 核心指導方針的界限設定檔會嘗試消除記憶體的不安全操作。 它可協助您避免使用未經檢查的原始指標和未核取的作業。 執行對緩衝區的統一範圍檢查存取方式之一,就是使用 gsl::at() 來自指導方針支援程式庫的公用程式。 也適合依賴 STL 容器中可用的標準實作 at()

此規則有助於尋找透過呼叫 operator[] 執行可能未核取存取的位置。 在大部分情況下,您可以使用 來取代這類呼叫 gsl::at()

  • 當下標運算子中使用非常數索引時,會標幟已知大小的陣列存取。 常數索引是由 C26483 STATIC_INDEX_OUT_OF_RANGE 處理。
  • 在多載 operator[] 呼叫上發出警告的邏輯比較複雜:
    • 如果索引為非整數,則會忽略呼叫。 這也會處理標準對應中的索引,因為這類運算子中的參數會以傳址方式傳遞。
    • 如果運算子標示為非擲回(使用 noexceptthrow()__declspec(nothrow) ),則會標示呼叫。 我們假設如果下標運算子永遠不會擲回例外狀況,它就不會執行範圍檢查,或這些檢查是模糊不清的。
    • 如果運算子未標示為非擲回,則如果運算子來自也會定義傳統 at() 成員函式的 STL 容器,則可能會標示它。 這類函式會透過簡單的名稱比對來偵測。
    • 規則不會對標準 at() 函式的呼叫發出警告。 這些函式是安全的;以 取代它們 gsl::at() 不會帶來太多價值。
  • 索引到 std::basic_string_view<> 是不安全的,因此發出警告。 使用 gsl::basic_string_span<> 取代標準,此標準 string_view 一律會進行界限檢查。
  • 實作不會考慮範圍檢查使用者程式碼在迴圈或分支中可能有某處。 在這裡,正確性會針對效能進行交易。 一般而言,您通常可以使用更可靠的反覆運算器或更精簡的增強 for 式 -迴圈來取代明確的範圍檢查。

範例

此範例示範函式如何 gsl::at 取代索引參考:

// C26446.cpp
#include <vector>
#include <gsl/gsl_util>
#include <iostream>

void fn()
{
    std::vector<int> v{1, 2, 3, 4, 5};
  
    // Normal bracket operators do not prevent you from accessing memory out of bounds.
    std::cout << v[5] << '\n';  // C26446, prefer using gsl::at instead of using operator[].
  
    // gsl::at prevents accessing memory out of bounds and invokes std::terminate on access.
    std::cout << gsl::at(v, 5) << '\n';
}