- 締切済み
未使用引数の注意文出力を回避するには
他種CPUの古いCソースをSH版に移植中なのですが、日立SHCコンパイラの オプション -ME でメッセージ出力抑制を解除すると大量の注意文が出力されて対処に 困っています。 その中で、C0012 (I) Unused variable "~" について、関数の取り合い仕様で引数が規定されているが、関数内処理では使われない 場合に注意文の出力を回避したいのですが、何かいい対策案ないでしょうか? int func( int a,int *b ){ return(0); } これまで分かっていることは 1)コンパイラは出荷済み他製品と共通なのでバージョンを上げられない。 2)-NOME=12 の出力抑制オプションは自動変数の未使用も検出しなくなるので不可。 (コンパイラも現状バージョンは番号指定に未対応です) 3)return(0); の後ろに a=0;b=0; と入れるとC0003 (I) Unreachable statementが出る。 4)変数属性の unused はコンパイラが未対応。 対策案の一つとして、関数内に if(a==0){} if(b==0){} を入れるというのがあるのですが、余分な機械語を生成しないか不安で検討中です。
- みんなの回答 (7)
- 専門家の回答
みんなの回答
- charmer29-2
- ベストアンサー率25% (41/159)
int func(int, int *) { return(0); } ではダメですか? C++なら通るので、もしかしたら通るのではないかと思うのですが。 #既にお試しでしたらご寛恕願います。
- jacta
- ベストアンサー率26% (845/3158)
最後に可能性があるとすれば、 __inline void f() {} というインライン関数を定義して、f(a)とかf(b)のように、実引数として渡したということにするぐらいしかないですね。 関数原型がないので、どんな型でも渡せますし、関数定義側では仮引数を記述していないので未使用云々の警告も出ないはずです。また、普通に最適化されれば、何一つ命令は発生しないはずです。 ただし、実引数と仮引数の数が一致しないので、規格上は動作が未定義になります。未定義にならないようにするには、 __inline int f(int arg, ...) { return arg; } ですかね。これで (void)f(0,a) なら、コンパイラや静的検証ツールの警告は黙らせそうです。機械語が生成されるかどうかは微妙ですが...。
お礼
ありがとうございました。 インライン展開部を最適化して機械語が消滅すると注意文が出ました。 結局、引数を使用するための対策コーディングは可能だが、追加した コードが機械語を生成しなければ、別の注意文が出てしまうという話 のようですね。
- Oh-Orange
- ベストアンサー率63% (854/1345)
★回答者 No.3 です。 ・カッコはマクロの引数が式だった場合に1つの式と評価させて代入させるためです。 それ以外は特に意味はありません。 ・それで、『UNREFERENCED_PARAMETER』マクロ関数が『WinNT.h』で定義されているので 覗いてみましたら次のような定義になっていました。 #if !defined(lint) #define UNREFERENCED_PARAMETER(P) (P) #else // lint // Note: lint -e530 says don't complain about uninitialized variables for // this varible. Error 527 has to do with unreachable code. // -restore restores checking to the -save state #define UNREFERENCED_PARAMETER(P)\ /*lint -save -e527 -e530 */\ {\ (P) = (P);\ }\ /*lint -restore */ #endif // lint ・定義内容を見ましたら『lint』が定義されていないと 『#define UNREFERENCED_PARAMETER(P) (P)』を定義して、『lint』があれば 『#define UNREFERENCED_PARAMETER(P) {(P)=(P);}』と定義するようです。 ・他にも似たようなマクロが定義されていました。 『#define DBG_UNREFERENCED_PARAMETER(P) (P)』 『#define DBG_UNREFERENCED_LOCAL_VARIABLE(V) (V)』 ・となっていたので『UNREFERENCED_PARAMETER』マクロ関数は 『#define UNREFERENCED_PARAMETER(P) (P)』と定義してみたらどうでしょう。 ・以上。おわり。→試してみて下さい。
お礼
ありがとうございます。 ...結果は同じでした。(しくしく GNUだとunused宣言できるようですし、マイクロソフトさんもそれで抑制できるように してるんでしょうね。 ということで、今候補に考えているのは(面倒なんだけど)、メイクファイルを2つ作り、 コンパイルオプション -define=~=~ でソースに異なる引数を与えて条件コンパイル するという案です。 コーディング中のコンパイルでは、注意文対策を有効にして注意文全般は出力許可する。 ( -defineDBG_CHK=1 -me ) 実働用のコンパイルでは、注意文対策をコメントアウトして注意文全般は出力抑制する。 ( -defineDBG_CHK=0 -nome ) でソースに #if DBG_CHK if(a){} if(b){} if(c){} if(d){} #endif こんな感じです。
- Tacosan
- ベストアンサー率23% (3656/15482)
lint的には /* ARGSUSED */ ってコメントを入れておくんだけど....
- Oh-Orange
- ベストアンサー率63% (854/1345)
★私も回答者 No.1 さんと同じです。 ・『return』文よりも前に『a=a;』、『b=b;』の代入式を記述すれば警告メッセージは出なくなります。 ・私は『UNREFERENCED_PARAMETER』マクロを使っています。 UNREFERENCED_PARAMETER( a ); UNREFERENCED_PARAMETER( b ); と使います。→『日立SHCコンパイラ』にこのマクロがあるか分かりませんが、あれば利用しましょう。 機能は『a=a;』や『b=b;』と同じです。 ・よって、ない場合はご自分で #define 定義すれば今後の環境に移植しやすいと思います。 #define UNREFERENCED_PARAMETER(c) (c=(c)) ・また、代入文として機械語に展開される事を気にしているようですが、コンパイラの最適化の処理で 最近のコンパイラは展開されることはないと思います。→昔、MSC Ver.6.0 を使っていましたがアセンブラ出力 のオプションで展開後のファイルを出力したとき、『a=a;』や『b=b;』の代入式は展開されていませんでした。 昔から、未使用変数の警告メッセージはうっとうしいので『a=a;』などと記述していましたが、Win32 API 環境で 『UNREFERENCED_PARAMETER』マクロを見つけてからはずっと利用しています。 ・以上。未使用変数の対策アドバイスでした。
お礼
ありがとうございます。 ANo.1の時のお礼に追記が漏れていたことをお詫びします。 a=a;を記述すると、ANo.2のお礼と同様に、コードを生成しない行に関する メッセージが出力されます。 最適化オプションを変えながらアセンブラ出力を眺めてみましたが、 最適化オプションを入れても抜いてもa=a;はコード展開されませんでした。 御指南されたマクロ定義も、SHCにはなかったので#defineしてみましたが 同じ結果でした。 ところで#defineの置換先に付いている括弧は何か意図があるのでしょうか?
- jacta
- ベストアンサー率26% (845/3158)
オプション等でどうにかするのであれば、-MEを止めるのが妥当なような気もします。 # たぶん、止められない理由があるのでしょうが... > 対策案の一つとして、関数内に > if(a==0){} if(b==0){} > を入れるというのがあるのですが、余分な機械語を生成しないか不安で検討中です。 コンパイル結果を見て確認するしかありませんが、将来、(今回のように)他の環境に移植する可能性なども考慮すると、確実性は乏しいですね。 とりあえず関数内に式を書いて何とかするのであれば、 (void)sizeof(a); (void)sizeof(b); とすれば余計なコードが生成される可能性はまずありませんが、このような対策はあまりお勧めできません。それに、今回の警告は出なくなっても、別の警告が出るかも知れませんし、コンパイラは寡黙になっても、外部の静的検証ツールが騒ぎ出す可能性もあります。 やはり、-MEを止めるか、警告は出たままにする方がよいと思います。
お礼
ありがとうございます。 C0010 (I) Elimination of needless expression (不要な式)が出ました。(しくしく 「これが出ない=コードが生成される」だとだめっぽいですね。 >止められない理由 コメントネスティングと上に書いた自動変数の未使用などは記述ミスで 起きる可能性が高いので、できればチェックとして利用したいのです。
> 注意文の出力を回避したい return の「前」(後ろに何を書いても無意味です)に、 a = a; b = b; という、一見無意味なような、それでいて引数はちゃんと使っているような、 そんな文を書いてみてはどうでしょうか。
お礼
ありがとうございます。 その行が代入文として機械語に展開され処理時間を浪費するのを避けたいので、 どう記述すればどう展開されるか検証してみます。
お礼
ありがとうございます。 C2137 (E) Null declaration for parameter で通さないらしいです。(しくしく