MISRA C++:2023?,MISRAC++標準的下一個版本,就在這里!為了幫助您了解MISRA C++:2023與上一版本之間的變化,我們繼續Perforce首席技術支持工程師Frank van den Beuken博士撰寫的第三期博客系列。
在前兩篇博客中,我們向您介紹了新的 MISRA C++ 標準和C++ 的歷史。在這篇博客中,我們將仔細研究以 C++ 中for循環為中心的特定規則。
什么是 MISRA C++:2023Rule9.5.2,為什么它很重要?
MISRA C++:2023引入了規則9.5.2,“ for范圍初始值設定項 最多應包含一個函數調用”,以避免在基于范圍的for語句的for范圍初始值設定項創建臨時對象時可能發生的未定義行為。
為了理解為什么會發生這種情況,讓我們仔細看看基于 C++ 范圍的for循環。
什么是 C++ 中基于范圍的for循環?
在編程中,循環用于重復代碼塊。當您知道要在代碼塊中循環多少次時,請使用for循環。
C++ 基于范圍的for循環是在C++11中引入的,作為容器迭代的簡潔表示法。
傳統循環源自 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++:2023Rule9.5.2 如何防范未定義的行為
MISRA C++:2023Rule9.5.2 旨在防止這種情況。MISRA C++:2023引入了規則9.5.2,該規則 要求for范圍初始值設定項最多應包含一個函數調用。
它還建議通過在循環范圍之前的單獨聲明中執行內部函數調用來解決此問題。例如:
auto strings = createStrings(); for ( auto c: strings[0] ) { std::cout << c << " "; }? |
現在,初始值設定項中只有一個函數調用,因此生存期擴展具有所需的效果,并且行為已完全定義。
請注意,此問題已在 C++23 中得到解決,其中初始值設定項的所有臨時項的生存期已擴展到整個for語句。
使用 Helix QAC 執行MISRA C++:2023規則
Perforce 的Helix QAC是一種靜態分析工具,在提供 MISRA C 和MISRA C++合規性檢查以及許多其他有價值的分析功能方面處于領先地位。
Helix QAC 通過其標準合規性模塊為MISRA C++:2023規則提供100%的強制執行覆蓋率,現已推出。靜態分析工具查找并報告C和C++中違反MISRA規則和指令的情況。
歡迎聯系北匯信息,申請Helix QAC試用。
-
C語言
+關注
關注
180文章
7604瀏覽量
136813 -
代碼
+關注
關注
30文章
4788瀏覽量
68603 -
MISRA
+關注
關注
0文章
21瀏覽量
6968
發布評論請先 登錄
相關推薦
評論