Soru Bir std :: vektörü bildirildiğinde ancak hiç kullanılmadığında derleyici neden uyarı vermiyor? [çift]


Bu sorunun zaten bir cevabı var:

#include <vector>

class Object
{
};

int main()
{
    Object myObject;
    std::vector<int> myVector;
}

Derleyici yayıyor:

warning: unused variable 'myObject' [-Wunused-variable]

İçin uyarı yok myVector. Niye ya? Bunu etkinleştirmenin bir yolu var mı?


17
2018-06-20 08:47


Menşei


C ++ 'da, kurucular ve yıkıcılar, belirgin olmayan mantık içerebilirler. Bu nedenle, genel olarak, kullanılmayan bir değişken bildirimin gerçekten elimine edilip edilmeyeceği kararsızdır. - pyon
Nesneye nontrivial sıfır parametresi yapıcı eklediğinizde uyarı veriyor mu? - lorro


Cevaplar:


Beyan etmenin (ve dolayısıyla başlatma ve bir noktada yıkımın) keyfi bir nesnenin genel olarak görünür yan etkileri bulunup bulunmadığı. Yapıcı, tanımlayıcısı derleyici tarafından bilinmeyen işlevleri çağrıştırabilir veya problemi kararsız hale getiren dışsal duruma veya başka bir yöne bağlı olabilir.

İlk durumda, kurucu, yıkıcı için aynı önemsizdir (hatta beyan edilmez). Gibi Object Üyeleri yok, açık ve kolayca tespit edilebilir Object foo Aslında hiçbir şey yapmaz.

std::vector bellek tahsis eden önemsiz bir kurucuya sahiptir (tanımı bilinemeyen dış durum + işlevi)new ...)) önemsiz olmayan bir yıkıcı ile birlikte (aynı zamanda tanımı bilinmeyen dış durum + işlevi)delete ...)). Bildirimi kaldırmak güvenli olup olmadığına bakılmaksızın (bu durumda belki de yapmanız gereken bir uyarı ipucu vermek mümkün değildir) bu durumda derleyici koddaki bildirimi terk etmek zorundadır (ve bildirimin bir sebebi).

Asal bir örnek std::lock_guard Bir muteks oluşturulduğunda kilitlenir ve imha edildiğinde otomatik olarak açılır. Muteks, nesne kapsam içinde olduğu sürece tutulur; genellikle sen erişemezsin std::lock_guard Her ne olursa olsun nesne - yine de bildirmek için yararlıdır. Bu işte RAII prensibidir.

Bu gibi durumlarda bir uyarı vermek, uyarıyı kapatan kişilere yol açan bir baş belası olabilir ve bu da uyarının işe yaramayacağını gösterir. (Derleyici, en iyi duruma getirme sırasında bildirimi kaldırmışsa yalnızca uyarıyı yayabilecek şekilde tasarlanabilir; bu, bazı uyarılar yalnızca bazı optimizasyonların etkinleştirildiğinde ortaya çıkmasının nedeni de budur.)


21
2018-06-20 08:53





Bu uyarı sadece önemsiz türler için üretilir. Derleyici, yapının herhangi bir harici işlevi çağırıp çağıramayacağını belirleyemiyor. Eğer sizin için bir kurucu eklerseniz Object sınıf sonra derleyici de bir uyarı verir. Gcc bu uyarıyı oluşturması gereken türlerin etiketlenmesine izin verir, bunu kullanarak yapabilirsiniz __attribute__((warn_unused)) :

http://coliru.stacked-crooked.com/a/0130c8ef29c121a1

örnek:

class __attribute__((warn_unused)) Object
{
    public:
    Object(){}
    void use() {}
};

int main()
{
    Object myObject;  // will give : warning: unused variable 'myObject' [-Wunused-variable]
    //myObject.use(); // uncomment to hide this warning
}

[Düzenle]

gcc öznitelikleri sayfasından: https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html :

warn_unused Önemsiz kurucular ile C ++ türleri ve / veya   yıkıcılar için derleyicinin   Bu türden bir değişken, başvurulmamışsa gerçekten kullanılmaz. Bu   type özniteliği, bu tür değişkenlerin derleyiciye bildirmesi gerektiğini bildirir.   Kullanılmamış gibi görünecekleri konusunda uyarılmalıdır.   temel türler. Bu özellik sadece   std :: string gibi bir değeri temsil eder; bu uygun değil   std :: lock_guard gibi bir kaynağı kontrol eden türler.

Bu özellik C de kabul edilir, ancak C çünkü gereksizdir   kurucular veya yıkıcılar yok.


6
2018-06-20 09:05



Yani, libstdc ++ bu özellik ile türlerinin çoğunu işaretlemeli mi? Bunun yerine kilit ve benzer türler için no_warn_unused öznitelikleri var mı ve varsayılan olarak uyarılmalı mı? - Marc Glisse
@MarcGlisse haklısınız (libstdc ++ 'nın% 99'unu işaretliyorum) ve burada bu konuda açık tartışma var: gcc.gnu.org/bugzilla/show_bug.cgi?id=55203. - marcinj
Marc'a katılıyorum, varsayılan davranış olmalı. - Jovini


Yukarıdaki cevapların yanı sıra, derleyici belgelerinizi de kontrol edin. Bazı derleyiciler, aynı uyarıyı birden çok kez göstermeyecek şekilde ayarlanabilir. "MyObject" bildirimini açıklarsanız, "myVector" için aynı uyarıyı alabilirsiniz. İlk önce bu uyarıyı üreten "mObject" ile "myVector" için uyarı alamazsınız.

Uyarılar durumunda derleyici davranışı çok derleyiciye özgüdür, bu nedenle tüm derleyicilerin aynı şekilde çalıştığını varsaymayın. :)


2
2018-06-20 09:59