主頁 > 軟體工程 > 這是一個真正的問題:警告C4172:回傳區域變數或臨時變數的地址

這是一個真正的問題:警告C4172:回傳區域變數或臨時變數的地址

2021-12-28 00:58:09 軟體工程

以下代碼洗掉警告 C4172:使用 MSVC 在 Windows 下回傳區域變數或臨時變數的地址。但我想知道在這種情況下它是否是一個真正的錯誤?我知道這里有很多類似的主題,我從這個警告中閱讀了很多類似的主題。所以在這種情況下,回傳值是一個來自“main”函式的指標,它應該一直存在到程式結束。如果returningLocalPointer 會回傳:“A something; return &something;” 那么是的,這將是一個問題,但在這種情況下,我們回傳一個存在直到“main”結束的指標。還是我錯了?

class A
{
};

A* returningLocalPointer(A* a)
{
    return a;
}

template<typename T>
T const& doWarning(T const& b)
{
    A* c = returningLocalPointer(b);
    return c;            // error if uses call-by-value
}

int main()
{
    A d;
    auto m = doWarning(&d);       //run-time ERROR
}

uj5u.com熱心網友回復:

是的,這是一個真正的問題。您的程式的行為未定義。 c是與 參考的指標不同的物件b,其生命周期在 結??束時結束doWarning這兩個指標指向同一個A物件 ( d),但這并不意味著它們是同一個物件。


為了說明這一點,我將或多或少地逐行并使用圖表:

A d;
auto m = doWarning(&d);

這將創建一個A名為物件d并將指向該物件的匿名指標傳遞給doWarning我稍后會m講到,但現在正在播放的物件如下所示:

               d
┌─────┐       ┌─────┐
│     │       │     │
│  A* ├──────?│  A  │
│     │       │     │
└─────┘       └─────┘

template<typename T>
T const& doWarning(T const& b)
{

在這里,T將被推匯出為A*,因為那是傳遞給它的。 doWarning通過參考接受其引數,因此 的型別b將為A* const &也就是說,b是對指向dfrom的匿名指標的參考main

 b                                 d
┌───────────┐       ┌─────┐       ┌─────┐
│           │       │     │       │     │
│ A* const& ├──────?│  A* ├──────?│  A  │
│           │       │     │       │     │
└───────────┘       └─────┘       └─────┘

A* c = returningLocalPointer(b);

在這里,您創建了另一個指標 ,c它指向與 相同的物件b我不會看returningLocalPointer,因為它或多或少無關緊要。這條線可以被替換,A* c = b;什么都不會改變。您的物件現在如下所示:

 b                                 d
┌───────────┐       ┌─────┐       ┌─────┐
│           │       │     │       │     │
│ A* const& ├──────?│  A* ├──────?│  A  │
│           │       │     │       │     │
└───────────┘       └─────┘       └─────┘
                     c               │
                    ┌─────┐          │
                    │     │          │
                    │  A* ├──────────┘
                    │     │
                    └─────┘

如您所見,c是與 參考的物件不同的物件b


return c;

由于doWarning回傳 an A* const&(since Tis A*),這將初始化回傳值以參考區域變數c

 b                                 d
┌───────────┐       ┌─────┐       ┌─────┐
│           │       │     │       │     │
│ A* const& ├──────?│  A* ├──────?│  A  │
│           │       │     │       │     │
└───────────┘       └─────┘       └─────┘
return value         c               │
┌───────────┐       ┌─────┐          │
│           │       │     │          │
│ A* const& ├──────?│  A* ├──────────┘
│           │       │     │
└───────────┘       └─────┘

}

現在doWarning結束,因此它的區域變數c超出范圍并且它的生命周期結束。這使doWarning的回傳值懸而未決:

 b                                 d
┌───────────┐       ┌─────┐       ┌─────┐
│           │       │     │       │     │
│ A* const& ├──────?│  A* ├──────?│  A  │
│           │       │     │       │     │
└───────────┘       └─────┘       └─────┘

return value
┌───────────┐
│           │
│ A* const& ├──────? Nothing here anymore
│           │
└───────────┘

auto m = doWarning(&d);

現在我們回到m. auto本身永遠不會推斷出參考型別,因此m推斷出的型別為A*這意味著程式將嘗試復制doWarning回傳的參考所參考的指標doWarning參考的回傳值的指標不再存在。試圖復制一個不存在的物件是一個錯誤,如果一個程式這樣做,它的行為是未定義的。

uj5u.com熱心網友回復:

讓我們“實體化”這個函式T = A*(就像你用 呼叫它時那樣doWarning(&d)):

template
A* const& doWarning<A*>(A* const& b)
{
    A* c = returningLocalPointer(&b);
    return c;
}

您也許能夠看到問題出在哪里。c通過參考回傳,但它是一個立即銷毀的區域變數,因此doWarning將始終回傳一個懸空參考。

MSVC 似乎對指向本地的指標和指向本地的參考使用相同的警告,這就是為什么它在真正涉及參考時談論地址。GCC 警告可能更清楚:

In instantiation of 'const T& doWarning(const T&) [with T = A*]':
warning: reference to local variable 'c' returned [-Wreturn-local-addr]
    return c;            // error if uses call-by-value
           ^
note: declared here
    A* c = returningLocalPointer(b);
       ^

uj5u.com熱心網友回復:

您正在回傳對區域變數的參考,c因此您的代碼具有未定義的行為。你可能會“走運”,m最終會成為一個指標,d但不能保證。

此代碼將定義行為,因為它回傳對的參考d而不是對的參考,c但如果doWarning使用臨時值呼叫它,它仍將具有未定義的行為(因此可能仍會產生警告)

A* returningLocalPointer(A* a)
{
    return a;
}

template<typename T>
T const& doWarning(T const& b)
{
    A* c = returningLocalPointer(&b);
    return *c;
}

int main()
{
    A d;
    auto& m = doWarning(d);
    // Undefined behaviour
    auto& n = doWarning(A{});
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/394722.html

標籤:C 指针 模板 警告

上一篇:設定沒有設定器的模擬類的欄位

下一篇:我在C中的結構鏈表有問題

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • Git本地庫既關聯GitHub又關聯Gitee

    創建代碼倉庫 使用gitee舉例(github和gitee差不多) 1.在gitee右上角點擊+,選擇新建倉庫 ? 2.選擇填寫倉庫資訊,然后進行創建 ? 3.服務端已經準備好了,本地開始作準備 (1)Git 全域設定 git config --global user.name "成鈺" git c ......

    uj5u.com 2020-09-10 05:04:14 more
  • CODING DevOps 代碼質量實戰系列第二課,相約周三

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。**《DevOps 代碼質量實戰(PHP 版)》**為 CODING DevOps 代碼質量實戰系列的第二課,同時也是本系列的 PHP ......

    uj5u.com 2020-09-10 05:07:43 more
  • 推薦Scrum書籍

    推薦Scrum書籍 直接上干貨,推薦書籍清單如下(推薦有順序的哦) Scrum指南 Scrum精髓 Scrum敏捷軟體開發 Scrum捷徑 硝煙中的Scrum和XP : 我們如何實施Scrum 敏捷軟體開發:Scrum實戰指南 Scrum要素 大規模Scrum:大規模敏捷組織的設計 用戶故事地圖 用 ......

    uj5u.com 2020-09-10 05:07:45 more
  • CODING DevOps 代碼質量實戰系列最后一課,周四發車

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。 **《DevOps 代碼質量實戰(Java 版)》**為 CODING DevOps 代碼質量實戰系列的最后一課,同時也是本系列的 ......

    uj5u.com 2020-09-10 05:07:52 more
  • 敏捷軟體工程實踐書籍

    Scrum轉型想要做好,第一步先了解并真正落實Scrum,那么我推薦的Scrum書籍是要看懂并實踐的。第二步是團隊的工程實踐要做扎實。 下面推薦工程實踐書單: 重構:改善既有代碼的設計 決議極限編程 : 擁抱變化 代碼整潔代碼 程式員的職業素養 修改代碼的藝術 撰寫可讀代碼的藝術 測驗驅動開發 : ......

    uj5u.com 2020-09-10 05:07:55 more
  • Jenkins+svn+nginx實作windows環境自動部署vue前端專案

    前面文章介紹了Jenkins+svn+tomcat實作自動化部署,現在終于有空抽時間出來寫下Jenkins+svn+nginx實作自動部署vue前端專案。 jenkins的安裝和配置已經在前面文章進行介紹,下面介紹實作vue前端專案需要進行的哪些額外的步驟。 注意:在安裝jenkins和nginx的 ......

    uj5u.com 2020-09-10 05:08:49 more
  • CODING DevOps 微服務專案實戰系列第一課,明天等你

    CODING DevOps 微服務專案實戰系列第一課**《DevOps 微服務專案實戰:DevOps 初體驗》**將由 CODING DevOps 開發工程師 王寬老師 向大家介紹 DevOps 的基本理念,并探討為什么現代開發活動需要 DevOps,同時將以 eShopOnContainers 項 ......

    uj5u.com 2020-09-10 05:09:14 more
  • CODING DevOps 微服務專案實戰系列第二課來啦!

    近年來,工程專案的結構越來越復雜,需要接入合適的持續集成流水線形式,才能滿足更多變的需求,那么如何優雅地使用 CI 能力提升生產效率呢?CODING DevOps 微服務專案實戰系列第二課 《DevOps 微服務專案實戰:CI 進階用法》 將由 CODING DevOps 全堆疊工程師 何晨哲老師 向 ......

    uj5u.com 2020-09-10 05:09:33 more
  • CODING DevOps 微服務專案實戰系列最后一課,周四開講!

    隨著軟體工程越來越復雜化,如何在 Kubernetes 集群進行灰度發布成為了生產部署的”必修課“,而如何實作安全可控、自動化的灰度發布也成為了持續部署重點關注的問題。CODING DevOps 微服務專案實戰系列最后一課:**《DevOps 微服務專案實戰:基于 Nginx-ingress 的自動 ......

    uj5u.com 2020-09-10 05:10:00 more
  • CODING 儀表盤功能正式推出,實作作業資料可視化!

    CODING 儀表盤功能現已正式推出!該功能旨在用一張張統計卡片的形式,統計并展示使用 CODING 中所產生的資料。這意味著無需額外的設定,就可以收集歸納寶貴的作業資料并予之量化分析。這些海量的資料皆會以圖表或串列的方式躍然紙上,方便團隊成員隨時查看各專案的進度、狀態和指標,云端協作迎來真正意義上 ......

    uj5u.com 2020-09-10 05:11:01 more
最新发布
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:41:12 more
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:35:34 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:05:44 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:00:18 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:20:31 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:55 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:18:51 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:00 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:17:55 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:12:06 more