簡體   English   中英

為什么未使用的臨時對象沒有 gcc/g++ 警告?

[英]Why is there no gcc/g++ warning for unused temporaries?

考慮以下代碼:

void ListenerImpl::attach(boost::shared_ptr<ISubscriber> subscriber)
{
    boost::unique_lock<boost::mutex>(mtx);
    subscribers.push_back(subscriber);
}

void ListenerImpl::notify(MsgPtr msg)
{
    boost::unique_lock<boost::mutex>(mtx);

    //notify all subscribers
    BOOST_FOREACH(boost::shared_ptr<ISubscriber> subscriber, subscribers){
        subscriber->update(msg);
    }

}

(這是 GoF 中描述的觀察者模式的實現。)這里的用戶干預是為了保護 attach() 和 notify() 不同時運行,因此 boost::unique_lock。 目標是保護subscribers容器。

但是確實很難注意到這些鎖實際上只是臨時的(仔細看看,沒有為它們分配名稱)。 因此,當臨時對象被破壞時,互斥鎖上的鎖將立即釋放,即代碼不是線程安全的。 我希望在這種情況下會出現編譯器警告。 諸如“未使用的臨時”之類的東西。

更糟糕的是,cppcheck 也不會識別這個錯誤。 (cppcheck:ac/c++代碼分析工具http://sourceforge.net/apps/mediawiki/cppcheck/index.php?title=Main_Page

Gcc 對未使用的變量發出警告。 這里的臨時變量是一個未使用的變量,肯定是程序員疏忽的結果。 那么,為什么在這種情況下沒有警告呢? 也許發現這種情況太復雜了?

編譯器不會發出警告,因為您很可能正在更新構造函數中的一些static-member / global變量(這是有效且有意義的)。 例如:

struct A
{
  static int count;
  A () { count ++; }
};

現在,當您簡單地調用一個臨時:

A();

如果沒有發生這樣的更新,編譯器將不會深入A的構造函數並檢查是否發生了有用的事情。 它總是假設是一個有效的場景。 有很多這樣的案例可以指出與臨時工有關。

請注意,您提出的警告也將針對每個it++; ,在許多 for 循環中都可以找到。

iammilind 已經提到,有時它是有意創建並立即銷毀 temp:當有副作用時。

在模板元編程中,可能會創建和銷毀臨時對象,以防萬一用戶提供具有副作用的 class。 當使用沒有副作用的簡單 class 來實例化模板時,模板代碼的深處會出現警告。

因此,您提出的警告會有很多誤報 在虛假警告中很難找到真正的警告。

所以我希望編譯器供應商已經決定他們的時間最好花在其他地方。

嗯..我不確定,但這不能用普通的 c++ 來保護嗎?

class Mutex;
class Lock {
    Lock(Mutex *mutex);
};

int main() {
    Lock /* lock */ (&mtx);
    return 0;
}

使用 DJGPP 編譯時收到此編譯器警告:

C:\df>gxx -c a.cpp
a.cpp: In function 'int main()':
a.cpp:8:30: error: 'mtx' declared as reference but not initialized

如果我取消注釋“鎖定”並添加一個互斥變量,它編譯得很好。

所以如果你的“mtx”變量是一個指針。 如果您更改它並將其作為“&mtx”傳遞會發生什么。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM