C'de “kullanılmayan parametre” uyarıları nasıl bastırılır?


210

Örneğin:

Bool NullFunc(const struct timespec *when, const char *who)
{
   return TRUE;
}

C ++ ' /*...*/da parametrelerin etrafına yorum yapabildim . Ama elbette C'de değil, bana hata veriyor error: parameter name omitted.



4
@CiroSantilli Bu sorunun daha fazla oyu var, diğer soruyu yinelenen olarak işaretlemek daha iyi olurdu.
Sashoalm


-Wno-unused-parameter, çok gürültülü ve nadiren böcek esp yakalar. ne zaman -Wshadowkullanılır.
Trass3r

Yanıtlar:


297

Genellikle böyle bir makro yazarım:

#define UNUSED(x) (void)(x)

Bu makroyu kullanılmayan tüm parametreleriniz için kullanabilirsiniz. (Bunun herhangi bir derleyici üzerinde çalıştığını unutmayın.)

Örneğin:

void f(int x) {
    UNUSED(x);
    ...
}

45
Ben sadece (void) x'i doğrudan kullanıyorum
Prof. Falken

6
AFAIK'in tek taşınabilir yolu bu olsa da, daha sonra değişkeni kullanırsanız ve kullanılmayan çizgiyi kaldırmayı unutursanız bu durumun sıkıntısı yanıltıcı olabilir. bu yüzden GCC'nin kullanılmayanları güzel.
ideasman42

6
@CookSchelling: Ah ama böyle kullanmamalısın. Böyle bir şey yapın: void f(int x) {UNUSED(x);}.
İş

9
@Alcott çünkü (benim durumumda olduğu gibi) işlev, aynı imzayı kullanması gereken birçok işlevden biri olabilir, çünkü bir işlev işaretçisi tarafından başvurulur.
josch

17
Ben #define UNUSED(...) (void)(__VA_ARGS__)bunu birden çok değişkene uygulamak için izin verir kullanıyorum .
Matthew Mitchell

110

Gcc'de, parametreyi unusedöznitelikle etiketleyebilirsiniz .

Bir değişkene bağlı olan bu özellik, değişkenin muhtemelen kullanılmayacağı anlamına gelir . GCC bu değişken için uyarı vermeyecektir.

Pratikte bu, __attribute__ ((unused))parametrenin hemen önüne getirilerek gerçekleştirilir . Örneğin:

void foo(workerid_t workerId) { }

olur

void foo(__attribute__((unused)) workerid_t workerId) { }

24
Benim gibi yeni başlayanlar için bu __attribute__ ((unused)), tartışmanın önüne geçmek anlamına gelir .
josch

2
@josch Ben tamamen doğru olduğunu düşünüyorum, ama belgeler parametre sonra koymak gerektiğini ima gibi görünüyor . Her iki seçenek de muhtemelen sorunsuz bir şekilde desteklenmektedir.
Antonio

Ayrıca __attribute__((unused)), tescilli bir GCC uzantısı olduğuna dikkat edin . Bazı derleyiciler tarafından destekleniyor, ancak bunun MSVC ile çalışmadığını varsayıyorum. Yine de derleyici standardının bir parçası değil, bu yüzden bu diğer bazı seçenekler kadar taşınabilir değil
Zoe

58

Gcc / clang'ın kullanılmayan özniteliğini kullanabilirsiniz, ancak kaynağın her yerinde gcc'ye özgü özniteliklere sahip olmaktan kaçınmak için bir başlıkta bu makroları kullanıyorum, ayrıca __attribute__her yerde biraz ayrıntılı / çirkin.

#ifdef __GNUC__
#  define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
#else
#  define UNUSED(x) UNUSED_ ## x
#endif

#ifdef __GNUC__
#  define UNUSED_FUNCTION(x) __attribute__((__unused__)) UNUSED_ ## x
#else
#  define UNUSED_FUNCTION(x) UNUSED_ ## x
#endif

Sonra yapabilirsin ...

void foo(int UNUSED(bar)) { ... }

barYanlışlıkla özniteliği bırakamazsınız böylece herhangi bir yerde kodu kullanmayı denerseniz bir hata alırsınız çünkü bunu tercih ederim .

ve fonksiyonlar için ...

static void UNUSED_FUNCTION(foo)(int bar) { ... }

Not 1):
Bildiğim kadarıyla MSVC'nin eşdeğeri yok __attribute__((__unused__)).

Not 2): Makro, parantez içeren bir bağımsız değişkenler için değil iş olacak Eğer böyle bir tartışmayı varsa o kadar sen olamaz yapmak, ya da hiç, bu tek dezavantajı ise makro Şu ana kadar bulunan bu durumlarda Geri çekilmelerini için
UNUSED
float (*coords)[3]
float UNUSED((*coords)[3])float (*UNUSED(coords))[3]UNUSED(void)coords;


Ya da sadece #define __attribute__(x)GCC olmayan ortamlar için (AFAIK hiçbiri __attribute__MSVC tarafından desteklenmez)?
Franklin Yu

Bu işe yarayabilir, ancak dunder prefixed terimler derleyici için ayrılmıştır, bu yüzden bunu önlemek istiyorum.
17:22

Benim gcc için en azından öznitelik belirtecini işlevler, vars ve parametre için doğru gibi görünmeden önce koymak, böylece #define POSSIBLY_UNUSED (tanımlayıcı) öznitelik __ ((__ kullanılmayan )) tanımlayıcı gibi üç şey için de kullanılabilir
Britton Kerin

warning: unused parameter ‘foo’ [-Wunused-parameter]
Aldıktan

19

Kullanılmayan özelliğe sahip gcc ile:

int foo (__attribute__((unused)) int bar) {
    return 0;
}

16

Bunun gcc olarak işaretlendiğini görünce, komut satırı anahtarını kullanabilirsiniz Wno-unused-parameter.

Örneğin:

gcc -Wno-unused-parameter test.c

Tabii ki bu, tüm dosyayı etkiler (ve belki de anahtarı ayarladığınız yere bağlı olarak), ancak herhangi bir kodu değiştirmeniz gerekmez.


7

Bir kaynak kodu bloğu için kullanılmayan parametre uyarısını bastırmanın gcc / g ++ 'a özgü bir yolu, onu aşağıdaki pragma ifadeleriyle kapsamaktır:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
<code with unused parameters here>
#pragma GCC diagnostic pop

Clang bu teşhis pragmalarını da destekliyor clang.llvm.org/docs/…
eush77

4

Özelliğin etiketlenmesi ideal bir yoldur. MACRO bazen karışıklığa yol açar. ve void (x) kullanarak, işleme yükü ekliyoruz.

Girdi bağımsız değişkeni kullanılmıyorsa,

void foo(int __attribute__((unused))key)
{
}

İşlev içinde tanımlanan değişkeni kullanmıyorsanız

void foo(int key)
{
   int hash = 0;
   int bkt __attribute__((unused)) = 0;

   api_call(x, hash, bkt);
}

Şimdi daha sonra mantık için karma değişkenini kullanmak ama bkt gerekmez. bkt'yi kullanılmamış olarak tanımlayın, aksi takdirde derleyici 'bkt set bt kullanılmaz' der.

NOT: Bu sadece optimizasyon için değil uyarıyı bastırmak içindir.


1
Kullanarak işleme yükü eklemezsiniz void(x), derleyici bunu optimize eder.
Majora320

4

Ben de aynı problemi yaşadım. Üçüncü bölüm bir kütüphane kullandım. Bu kütüphaneyi derlediğimde, derleyici (gcc / clang) kullanılmayan değişkenlerden şikayet edecek.

Bunun gibi

test.cpp: 29: 11: uyarı: değişken 'büyü' kümesi ancak kullanılmıyor [-Wunused-but-set-variable] short magic [] = {

test.cpp: 84: 17: uyarı: kullanılmayan değişken 'before_write' [-Wunused-değişken] int64_t before_write = Thread :: currentTimeMillis ();

Yani çözüm oldukça açık. -Wno-unusedGcc / clang CFLAG olarak eklemek , ayarlamış olduğunuz düşünülse bile tüm "kullanılmayan" uyarıları engelleyecektir -Wall.

Bu şekilde, herhangi bir kodu değiştirmeniz GEREKMEZ.


1
Kullanılmayan tüm uyarıları gerçekten göz ardı etmek istiyorsanız, bu iyi, ancak neredeyse hiç böyle değil. Genellikle yalnızca yoksaymak istediğiniz belirli örneklerdir.
Dan Bechard

1

MSVC'de belirli bir uyarıyı bastırmak için derleyicinin numarasını / wd # olarak belirtmek yeterlidir. CMakeLists.txt dosyam böyle bir blok içeriyor:

If (MSVC)
    Set (CMAKE_EXE_LINKER_FLAGS "$ {CMAKE_EXE_LINKER_FLAGS} / NODEFAULTLIB: LIBCMT")
    Add_definitions (/W4 /wd4512 /wd4702 /wd4100 /wd4510 /wd4355 /wd4127)
    Add_definitions (/D_CRT_SECURE_NO_WARNINGS)
Elseif (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUC)
    Add_definitions (-Wall -W -pedantic)
Else ()
    Message ("Unknown compiler")
Endif ()

Şimdi tam olarak ne olduğunu söyleyemem / wd4512 / wd4702 / wd4100 / wd4510 / wd4355 / wd4127, çünkü üç yıl boyunca MSVC'ye dikkat etmiyorum, ancak sonucu etkilemeyen süperpetalik uyarıları bastırıyorlar.


0

Bu tarzın kullanıldığını gördüm:

if (when || who || format || data || len);

14
Hm. Bu gibi tüm parametreleri bir boole dönüştürülebileceğini varsayar gibi ben böyle diyemeyiz.
Suma

1
Derleyici neredeyse kesinlikle optimize edecek olsa da, bu gerçekten iyi bir kongre değil, neler olup bittiğini net değil ve statik kaynak denetleyicilerini karıştırabilir. Buradaki diğer önerilerden birini daha iyi kullanın.
ideasman42

1
Buna hala cevap geldiğime inanamıyorum. Soru, bunun C için olduğunu belirtti. Evet, başka bir dilde bu işe yaramayacaktı.
Iustin

2
Yenilik faktörü için bunu + 1 kullanmazdım.
mgalgs

2
Değişkenlerin gerçekliğini kontrol etmek yapılar için uyarılar verebilir. Örneğin. struct { int a; } b = {1}; if (b);GCC uyarıyor used struct type value where scalar is required,.
ideasman42

-1

Kayıt için, Job'un cevabını beğendim, ancak değişken adını tek başına "hiçbir şey" ifadesinde kullanan bir çözüm merak ediyorum:

void foo(int x) {
    x; /* unused */
    ...
}

Tabii, bunun dezavantajları var; örneğin, "kullanılmayan" not olmadan, kasıtlı bir kod satırı yerine bir hata gibi görünür.

Bunun yararı, DEFINE'a ihtiyaç duyulmaması ve uyarıyı ortadan kaldırmasıdır.

Performans, optimizasyon veya başka farklılıklar var mı?


2
Ben ya MSVC ile kullandım, ancak GCC "etkisi olmadan ifade" uyarısı yükseltir. Yani, Job'un çözümü gitmenin yoludur.
Dmitrii Semikin

Bu yaklaşım hala
XCode'da
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.