Taa1989
@Taa1989

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

エラーに関する質問です

解決したいこと

動画を見ながら勉強してたのですが、%dで小数点の計算した時、動画の方だとWARNINGエラー表示がされてるんですが、自分が作った方は表示されません、動画のようにするにはどうしたらいいのでしょう

動画だとこのように表示されてます
Screenshot_20240127-073804~2.png

自分で書いた方です

スクリーンショット 2024-01-27 084649_085246.png

0

4Answer

使っている処理系が gccclang なら -Wall オプションを付ければ主要な問題点は指摘してくれるはずです。 もっと厳密にしたいなら -Wextra-pedantic も付ければよいでしょう。

C の型システムでは型チェックを緩めるような形で可変長引数を実現しています。 型の不整合として検出することが出来ないのです。 チェックを緩める分はプログラマが責任をもって正しく扱わなければなりません。 正しくないときにどのような結果を引き起こすかは言語仕様では未定義です。

現代的な処理系は printf などの主要な関数は特別扱いで問題点をチェックしてくれることもありますが、 可変長引数一般では必ずしもそうではありませんし、処理系によっては検出する機能を持っていないこともあります。

C はそういうものなので問題点を処理系が指摘してくれるとは限らないことを前提にして規則を正しく理解する必要があります。 (もちろん可能な範囲では処理系や各種ツールで問題点をチェックする体制にするに越したことはないです。)

2Like

エラーを無理に表示させなくともプログラムが意図したように動作するなら、問題ないのでは?

1Like

Comments

  1. 実行結果は、

    -1717986919

    となるのでは? (Visual studio 2022 での結果)

    そうだとすると「意図したように動作」ではなさそうです。

ターミナルにその解説動画の通りに入力したらコンパイル時に警告が出ませんか?
(ファイル名は適宜変えてください、、、)

gcc -o sample sample.c && ./sample

あるいは、PowerShellで実行したコマンドの出力が欲しいのでしたら以下を参考に、、、

1Like

Comments

  1. Try It OnlineというサービスでPowerShell(v6.2.3)を使って確認しました。 
    スクリプトは以下のように動作します。
    ①sample.cを作成
    ②gcc(v8.3.1)でコンパイル
    ③sampleを実行

    sample.cを作成してコンパイル/実行してみる
    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
    

    Try it online!

    output
    
    
        Directory: /tmp/home
    
    Mode                LastWriteTime         Length Name
    ----                -------------         ------ ----
    ------           1/29/24 11:48 AM              0 sample.c
    -1076170376
    
    
    debug
    
    Real time: 1.031 s
    User time: 0.859 s
    Sys. time: 0.205 s
    CPU share: 103.24 %
    Exit code: 0
    

    アウトプットとデバッグにそれらしいエラーが出てないので-Wallオプションを付けて、、、

    -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
    

    Try it online!

    output
    
    
        Directory: /tmp/home
    
    Mode                LastWriteTime         Length Name
    ----                -------------         ------ ----
    ------           1/29/24 11:53 AM              0 sample.c
    -939153528
    
    
    debug
    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
    

    Try it online!

    output
    
    
        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
    
    
    debug
    
    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型) の型が一致することが好ましい(すべき)としてコンパイルします。

0Like

Your answer might help someone💌