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.