エラーに関する質問です
Q&A
解決したいこと
動画を見ながら勉強してたのですが、%dで小数点の計算した時、動画の方だとWARNINGエラー表示がされてるんですが、自分が作った方は表示されません、動画のようにするにはどうしたらいいのでしょう
自分で書いた方です
Q&A
動画を見ながら勉強してたのですが、%dで小数点の計算した時、動画の方だとWARNINGエラー表示がされてるんですが、自分が作った方は表示されません、動画のようにするにはどうしたらいいのでしょう
自分で書いた方です
使っている処理系が gcc
や clang
なら -Wall
オプションを付ければ主要な問題点は指摘してくれるはずです。 もっと厳密にしたいなら -Wextra
や -pedantic
も付ければよいでしょう。
C の型システムでは型チェックを緩めるような形で可変長引数を実現しています。 型の不整合として検出することが出来ないのです。 チェックを緩める分はプログラマが責任をもって正しく扱わなければなりません。 正しくないときにどのような結果を引き起こすかは言語仕様では未定義です。
現代的な処理系は printf
などの主要な関数は特別扱いで問題点をチェックしてくれることもありますが、 可変長引数一般では必ずしもそうではありませんし、処理系によっては検出する機能を持っていないこともあります。
C はそういうものなので問題点を処理系が指摘してくれるとは限らないことを前提にして規則を正しく理解する必要があります。 (もちろん可能な範囲では処理系や各種ツールで問題点をチェックする体制にするに越したことはないです。)
エラーを無理に表示させなくともプログラムが意図したように動作するなら、問題ないのでは?
実行結果は、
-1717986919
となるのでは? (Visual studio 2022 での結果)
そうだとすると「意図したように動作」ではなさそうです。
ターミナルにその解説動画の通りに入力したらコンパイル時に警告が出ませんか?
(ファイル名は適宜変えてください、、、)
gcc -o sample sample.c && ./sample
あるいは、PowerShellで実行したコマンドの出力が欲しいのでしたら以下を参考に、、、
Try It OnlineというサービスでPowerShell(v6.2.3)を使って確認しました。
スクリプトは以下のように動作します。
①sample.cを作成
②gcc(v8.3.1)でコンパイル
③sampleを実行
New-Item -Type FILE sample.c
@"
#include <stdio.h>
int main(void) {
printf("%d", 3.14*3*3);
return 0;
}
"@ > sample.c
gcc -o sample sample.c
./sample
Directory: /tmp/home
Mode LastWriteTime Length Name
---- ------------- ------ ----
------ 1/29/24 11:48 AM 0 sample.c
-1076170376
Real time: 1.031 s
User time: 0.859 s
Sys. time: 0.205 s
CPU share: 103.24 %
Exit code: 0
アウトプットとデバッグにそれらしいエラーが出てないので-Wall
オプションを付けて、、、
New-Item -Type FILE sample.c
@"
#include <stdio.h>
int main(void) {
printf("%d", 3.14*3*3);
return 0;
}
"@ > sample.c
gcc -Wall -o sample sample.c
./sample
Directory: /tmp/home
Mode LastWriteTime Length Name
---- ------------- ------ ----
------ 1/29/24 11:53 AM 0 sample.c
-939153528
sample.c: In function ‘main’:
sample.c:3:12: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘double’ [-Wformat=]
printf("%d", 3.14*3*3);
~^ ~~~~~~~~
%f
Real time: 0.856 s
User time: 0.696 s
Sys. time: 0.156 s
CPU share: 99.59 %
Exit code: 0
デバッグにエラーが出て来ました!でもアウトプットに出力して欲しいかも、、、
そこでgccでコンパイルしている箇所の最後に2>&1
(2:エラー出力を1:標準出力にリダイレクト)を追加。
New-Item -Type FILE sample.c
@"
#include <stdio.h>
int main(void) {
printf("%d", 3.14*3*3);
return 0;
}
"@ > sample.c
gcc -Wall -o sample sample.c 2>&1
./sample
Directory: /tmp/home
Mode LastWriteTime Length Name
---- ------------- ------ ----
------ 1/29/24 11:58 AM 0 sample.c
sample.c: In function ‘main’:
sample.c:3:12: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘double’ [-Wformat=]
printf("%d", 3.14*3*3);
~^ ~~~~~~~~
%f
325178808
Real time: 0.776 s
User time: 0.676 s
Sys. time: 0.149 s
CPU share: 106.41 %
Exit code: 0
アウトプットにエラーが出力されました。
もしも質問者さんが-Wall
付けてもエラーが表示されない場合、出力をリダイレクトされると表示されるかもしれません。
※この質問とは別のPowerShellのスクリプトの書き方という質問の回答に、スクリプトにエイリアスは使わないとありましたので、念の為touchコマンドはNew-Itemコマンドレットに変更しました。
コンパイラの設定が正しくないのでは?コンパイラの種類(OSの違い)、オプション指定の違いから生じるものでは? Hello World表示はできましたか?
良いサンプルがないのですみません。
そもそも、参考動画の作者が意図してWARNING表示させているならその意味を理解すべきです。
printf関数はint,double,char型に格納された値を文字列に変換して標準出力のデバイス(画面)に出力するものです。
その際、コンパイラは、"%d"(int型) と 3.14*3*3
(double型) の型が一致することが好ましい(すべき)としてコンパイルします。