首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C++ 變長陣列 (VLA) 陷阱:const 參數無法作為編譯期常數

     編輯:程式設計疑難解答

錯誤代碼

void merge_sort(int arr[], const int len) {
    int reg[len];  // ❌ 編譯錯誤:陣列大小必須為編譯期常數
    // ...
}

錯誤原因

const int len 是**執行期常數**(函式參數在呼叫時才決定值),而 C++ **標準不支援變長陣列 (VLA)**。int reg[len] 要求 len 為**編譯期常數常量** (如字面值、constexpr、#define、enum),編譯器才能在堆疊分配固定大小空間。

標準 C++ 解決方案

方案一:std::vector (推薦,自動管理記憶體)

void merge_sort(int arr[], int len) {
    std::vector reg(len);  // 動態分配在堆上,安全、無大小限制
    merge_sort_recursive(arr, reg.data(), 0, len - 1);
}

方案二:動態陣列 new/delete (C 風格)

void merge_sort(int arr[], int len) {
    int* reg = new int[len];
    merge_sort_recursive(arr, reg, 0, len - 1);
    delete[] reg;  // 必須釋放
}

方案三:模板參數化長度 (僅適用於編譯期已知大小)

template 
void merge_sort(int (&arr)[N]) {
    int reg[N];  // N 為編譯期常數,合法
    merge_sort_recursive(arr, reg, 0, N - 1);
}
// 呼叫:int a[10]; merge_sort(a); // 推導 N=10

方案四:C++20 std::dynarray / std::span (輔助)

// C++20 可用 std::span 統一介面
void merge_sort(std::span arr) {
    std::vector reg(arr.size());
    // ...
}

為什麼 GCC/Clang 編得過?

GCC/Clang 預設啟用 **GNU 延伸支援 VLA**,但這**不符合 C++ 標準**,跨平台移植 (MSVC、嵌入式編譯器) 會失敗。請加上 -pedantic-errors 或 -std=c++17 -Werror=vla 強制標準合規。

總結

函式參數 const int len **不是編譯期常數**,不能用於堆疊陣列大小。請改用 std::vector 或 new[]/delete[],符合標準且安全無大小限制。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved