- ベストアンサー
関数プロトタイプ無しで、引数がfloatの場合
- 関数プロトタイプ無しで、引数がfloatの場合につまずいています。
- 引数の型が合っているため、正常に実行できるように思われますが、結果がおかしくなってしまいます。
- プロトタイプがない場合でも、引数をdoubleに変更すると正常に実行されます。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
既に回答にあるように、プロトタイプがない場合、float は、double に「格上げ」されてから、関数に渡されます。 これは、大昔のC……その頃まだ、プロトタイプという概念もなかった頃(先行宣言はあった)、引数においては、 ・int より小さい整数(char も)は、int に ・float は、double に それぞれ格上げされてから関数に渡されると、そう決めた(知る人ぞ知る『K&R』の時代にまでさかのぼる)というのが前段にあるわけです。 ※なぜ、わざわざそう決めたのかは、わかりませんでした。 時代が下って、プロトタイプが存在するようになった現在、プロトタイプで決められた引数の型に対して、「代入するのと同じように」型変換(同じ型なら、もちろん、変換無し)されて受け渡されるようになりました。 ※ただし、printf() のような可変引数の部分は、「省略された引数リスト」ということで、プロトタイプの場合と同じ「格上げ」が発生する。 そういうわけで、プロトタイプなしで関数を呼び出したときに、引数が float だと、格上げの影響でdouble に変換されてから関数に渡されました。 受けとるほうの関数は、float が来たと思っているので、良くないことが起こりましたとそういうわけです。 引数が double だった場合には、格上げなど無しでそのまま渡されるので、(たまたま引数があっていれば)正常に実行されたというわけです。
その他の回答 (3)
- Tacosan
- ベストアンサー率23% (3656/15482)
ほんと~に初期のころは, 関数に引数として渡す時だけでなく, 式の中で使うときは常に ・int より小さい整数型 (char と short) は int にする ・float は double にする という変換をしてましたよね>#3. 「float で計算させるといったん double に変換してから計算するので遅くなる」という話を聞いたものです.
お礼
ありがとうございました。 そういえば、char は int にして計算されるというのは、聞いたことがありました。 float が一度 double に変換されるのも、聞いたことあるような。 それぞれ聞いたことはあるのに、なにか、頭の中でつながってなかった気がします。
- titokani
- ベストアンサー率19% (341/1726)
プロトタイプがない場合、floatはdoubleに変換されて渡されるのが規格です。
お礼
ありがとうございました。 何かおかしくなっていると思ったのは、double に変換されていたからなのですね。 int がおかしくなるとなんとか見当も付くのですが、浮動小数点でおかしくなると、お手上げでした。
- SaKaKashi
- ベストアンサー率24% (755/3136)
>・引数の型の不整合がないようにする 不整合をチェックして一致しなければエラーにする。 >・必要に応じて、仮引数と実引数の型変換を発生させる こんな事はしません。 >f と func() の引数を double にしたときには、プロトタイプがなくても、正常に実行されます。 偶然でしょうね。 関数プロトタイプがなくて、偶然の結果を信じる人が多くて、プロトタイプ書かなくてもいいと 言い張る人は多いです。 ま、宗教のようなものですから相手にしないことです。
補足
>・必要に応じて、仮引数と実引数の型変換を発生させる たとえば、 void func(int i); というプロトタイプに対して、 func(12.3); という呼び出しは、double -> int への型変換を発生させると思うのですが。 この場合、プロトタイプがないとコンパイルではエラーがなく(警告は出ますが)実行時には見事に失敗します。
お礼
ありがとうございました。 「格上げ」で、いろいろ検索してしまいました。 そいうえば、printf() の場合、float は、double に変換して渡されるというのは聞いたことがありました。 同じような話だったのですね。 ありがとうございました。