MISRA C++:2023——MISRA? C++ 標準的下一個版本來了!為了幫助您了解 MISRA C++:2023相比于之前版本的變化,我們將繼續為您帶來Perforce首席技術支持工程師Frank van den Beuken博士的博客系列,本期為第三篇。
在前兩篇系列文章中,我們向您介紹了新的MISRA C++ 標準和C++簡史。本文,我們將仔細研究C++中以for循環為中心的特定規則。
什么是MISRA C++:2023規則9.5.2,為什么它很重要?
MISRA C++:2023 引入了規則 9.5.2 “for-range 初始值設定項最多應包含一個函數調用”,以避免在基于范圍的for語句的 for-range初始值設定項創建臨時對象時可能發生的未定義行為。
要了解為什么會發生這種情況,讓我們仔細看看基于C++范圍的for循環。
C++中基于范圍的for循環是什么?
在編程中,循環用于重復代碼塊。當您知道要循環訪問代碼塊的次數時,可以使用for循環。
C++基于范圍的for循環是在C++ 11中引入的,作為容器迭代的簡潔表示法。
傳統的for循環起源于C語言,具有可選的循環初始化,然后是循環條件,最后是循環增量表達式。
傳統for循環可用于迭代容器,如下所示:
std::vector v = { "Example", "vector", "of", "strings" }; for ( auto &&i = v.begin(); i != v.end(); ++i ) { std::cout < *i < “ “; } std::cout < std::endl;
使用基于范圍的for循環,迭代器的使用是隱式的:
for ( auto &&s: v ) { std::cout < s < “ “; }
對于同一循環,這是一個更為簡單的表示法。C++語言標準規定,它是以下語言的縮寫:
{ auto && __range = v; auto __begin = __range; auto __end = v.end(); for (; __begin != __end; ++__begin) { auto &&s = *__begin; std::cout < s < “ “; } }
但是,此表示法存在局限性。在上面的示例中,__range 是用 v 初始化的,這是一個更簡單的變量,但也可以使用為其創建多個臨時對象的復雜表達式。
讓我們考慮使用一個函數,該函數返回字符串的向量,并具有:
一個循環,輸出以空格分隔的字符串,如上所述
打印第一個字符串的字母的第二個循環,用空格分隔:
std::vector createStrings() { return { "Example”, "vector", "of", "strings" }; } int main() { for ( auto w: createStrings() ) { std::cout < w < " "; } std::cout < std::endl; for ( auto c: createStrings()[0] ) { std::cout < c < " "; } std::cout < std::endl; }
如果我們執行此操作,第一個循環將按預期運行,但第二個循環卻調用了未定義的行為。問題是 createStrings()[0] 有兩個函數調用。最里面的調用是對 createStrings 的調用,最外層的調用是對索引運算符 []的調用。
出現未定義行為的原因是,“createStrings”返回的臨時對象被用作“operator[]”調用的參數,因此,根據C++的規則,臨時對象不會延長其生命周期。
MISRA C++:2023規則9.5.2 如何防范未定義行為
MISRA C++:2023規則 9.5.2 旨在防止這種情況。MISRA C++:2023引入了規則 9.5.2,該規則要求for-range-initializer應最多包含一個函數調用。
它還建議通過在range-for循環之前的單獨聲明中執行內部函數調用來解決此問題。例如:
auto strings = createStrings(); for ( auto c: strings[0] ) { std::cout < c < " "; }
現在,初始值設定項中只有一個函數調用,因此生命周期擴展就能達到預期效果,并且行為已完全定義。
請注意,此問題已在C++23 中得到解決,其中初始值設定項的所有臨時值的生命周期都擴展到整個for語句。
使用Perforce Helix QAC強制執行MISRA C++:2023 規則
Perforce的 Helix QAC 是一款靜態代碼分析工具,在提供 MISRA C 和 MISRA C++ 合規性檢查以及許多其他有價值的分析功能方面處于領先地位。
Helix QAC通過其標準的合規模塊為 MISRA C++:2023 規則提供 100% 的執行覆蓋率,該模塊現已推出。通過靜態分析工具Helix QAC可查找并報告C和 C++中違反MISRA規則和指令的行為。
- END -
文章來源:https://bit.ly/3VJY8yJ
作者簡介:
Frank van den Beuken,首席技術支持工程師
作為技術支持專家,Frank 在集成 Perforce 靜態源代碼分析解決方案方面擁有超過 20 年的經驗,可在客戶軟件開發環境中進行軟件質量控制。近年來,他專注于為各種編譯器配置靜態分析。他還提供代碼質量培訓和咨詢。Frank 在奈梅亨大學獲得數學和計算機科學博士學位,研究系統規范語言。
立即了解為什么Helix QAC是 MISRA C++的最佳靜態代碼分析器,歡迎咨詢Perforce中國授權合作伙伴——龍智:
審核編輯 黃宇
-
靜態
+關注
關注
1文章
29瀏覽量
14542 -
C++
+關注
關注
22文章
2108瀏覽量
73618 -
代碼
+關注
關注
30文章
4779瀏覽量
68521 -
MISRA
+關注
關注
0文章
21瀏覽量
6963
發布評論請先 登錄
相關推薦
評論