身為一個好的 C/C++ 碼農,CFLAGS 加入 -Wall -W -Werror 也是很合理的。

但在寫程式的時候,偶爾會遇到一種狀況是為了函式介面不變而必須傳一個用不到的變數,導致編譯器噴出以下錯誤

error: unused parameter 'arg' [-Werror,-Wunused-parameter]

對此,以下整理了幾種方法處理。

方法 1:利用轉型

將變數轉型雖然不會產生任何實際效果,但會讓編譯器認為這個變數有被使用,所以這個方法是有效的(笑)

void func(int arg) {
    (void) arg;
}

有些人不喜歡這個做法,因為轉型這個行為看起來並不直覺,所以會用 macro 把它包起來

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

void func(int arg) {
    UNUSED(arg);
}

方法 2:不要寫變數名稱 (C++)

解決不了問題,就解決產生問題的來源(疑?)

不寫變數名稱,就沒有變數沒被使用的問題了XD

void func(int arg) {
    // not ok
}

void func(int /* arg */) {
    // ok
}

方法 3:使用 std::ignore (C++11)

std::ignore 原先設計是用在 C++ tuple 上,當有函式的回傳值是 tuple 且其中有一個變數你不會用到時,可以使用 std::ignore 略過該回傳值,正規的 std::ignore 用法可以參考這邊

這個方法的缺點是必須 include tuple 這個你不一定有用到的 header,所以看起來會很奇怪。

#include <tuple>

void func(int arg) {
    std::ignore = arg;
}

值得一提的是,雖然這個方法看起來好像會產生無用的機器碼,但實際上不會,以下是可能的實作方式。由於 operator= 在這邊是 inline 且裡面只有 return *this,所以基本上不會產生什麼機器碼,也不會有 function call 的 jump

namespace std {

struct Ignore { 
   template <class _Type> 
   Ignore& operator= (const _Type& value) { return *this; }
}; 

Ignore ignore = Ignore ();

} // namespace std

方法 4:使用 function attribute unused (GCC/G++)

這個方法只有 gcc/g++ 適用,但滿多人用的所以可移植性應該還行。

void func(int arg __attribute__((unused))) {
    // ok
}

方法 5:使用 [[maybe_unused]] (C++17)

最後一個方法是使用 C++17 提供的 [[maybe_unused]],如果可以自己決定的話就打開 -std=c++17 吧!

void func([[maybe_unused]] int arg) {
    // ok
}
最後修改日期: 2019-08-12

留言

撰寫回覆或留言

發佈留言必須填寫的電子郵件地址不會公開。