• ベストアンサー

情報処理技術者試験は本当にC89?

情報処理技術者試験でのC言語の規格はC89とされています。 しかし、 int *p; p=(int *)malloc(sizeof(int)); のように,mallocの返り値をキャストしている問題文が過去にあります。一方、Wikipediaのmallocで調べてもC89のようなANSI規格ではキャストすべきでないとあり、あるサイトには「このキャストはC++との互換性のため」とも書かれています。初心者が受験する際に混乱します。 情報処理技術者試験でのC言語の規格は本当にC89なのでしょうか。「C++のことを気にしないとC言語が勉強できない」と誤解を与えるのでは。

質問者が選んだベストアンサー

  • ベストアンサー
  • R32C
  • ベストアンサー率39% (115/290)
回答No.11

"一般的に"キャストをつけるかつけないかということに話がそれていませんか? 本題は情報処理試験であり、お堅い試験問題かと思います。 「どちらかが明白に正しいという命題ではない」というのは、一般的には そうかと思いますが、 試験問題として「どちらかが明白に正しいという命題ではない」 ものを問題(問題の一部)にするのはいかがなものかと思います。

voronoi
質問者

お礼

回答ありがとうございます。 私の力不足のため議論がすすまず申し訳ありません。 最後に私なりに調べた結果をまとめました。

その他の回答 (13)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.3

脚注1に関しては、ウィキペディアの記述があまり適切ではありませんね。 関数原型がなければ警告が出る処理系が多いことは確かですが、規格上保証されているわけではありませんし、別のヘッダから間接的に<stdlib.h>がインクルードされている(そしてインクルードされるかどうかは実装依存)ような場合でも素通りしてしまいます。 しかし、そのことと、初心者が受験するため云々とは話が違います。ウィキペディアの記事に不服があるのなら、質問者さんご自身が適切に編集するか、少なくともその記事のノートに書くべきであり、このサイトで質問することは筋が違います。

voronoi
質問者

補足

誤解されています。私はWikipediaやCのFAQでのmallocの記述に対して何の不服もありません。それどころか、これらを正しく、また誤解も招かない記述だと思っています。だからこそ、質問内容のように情報処理技術者試験の出題側が言葉足らず、または誤解を招くことを行っているのではと疑問をもっています。例えば、私が探しあてられなかっただけで、出題においてC89に従うが以下に示すような例ではキャスト演算子を用いる、といった補足説明が存在し、情報処理技術者試験のホームページのXXにありますよ、とった答えを期待していました。また、このような指摘が出題側に既に寄せられており今後出題文に変化があるらしい、といった答えも予想していました。ただ、ご指摘の「関数原型..」の部分は私にはまだ勉強不足で理解できません。jacta さんは Wikipedia の記述の方が適切でない、と考えておられるわけですね。また、「編集..」はC++も知らない初心者の私ができるとは思っていません。また、Wikipediaの英文の方も編集すべきという話になってしまいますし。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

> wikipedia での脚注1に stdlib.h 忘れに対してキャストがあると困ったことになると書かれています。 脚注1って↓ですよね |stdlib.hをインクルードし忘れた場合、コンパイラはmallocがint型であるとみ |なす。これをキャストしているとインクルードし忘れたことに気づかないが、 |キャストしていないとコンパイル時にintをポインタ型変数に代入しようとしてい |るとして何らかのメッセージが表示される。 「困ったことになる」とは具体的にどれを指して言ってますか? またC言語FAQの方ですが |7.7: |mallocが返した値を確保したデータ型のポインターに注意深くキャスト |しているコードをたまに見るのはなぜか。 |A: |ANSI/ISO規格のC言語がvoid *という汎用のポインター型を導入するまでは、 |互換性のないポインター型の間で代入をするときに警告を黙らせるのに |こうしたキャストが必要となることがよくあった。 |(ANSI/ISO規格のCでは、こうしたキャストはもう必要ない。) のことを指しているのだと思いますが、 「必要ない」ことをやって害があるのなら それは止めるべきだとは思いますが、 大元とのサンプルとやらに関しては放置していいレベルのものだと思います。 ただ英文の方の FAQ 7.7 を見ると | But of course malloc does not return an int, | so trying to convert the int that it doesn't return | to a pointer is likely to lead to a | different kind of trouble, which will be harder to track down. という文はあります。 とはいうものの、実際にコンパイラに食わせてみると int main() { char *p; char *q; q = (char *)malloc(1024); p = malloc(1024); return 0; } >cl -nologo -W2 -c mmm.c mmm.c mmm.c(8) : warning C4047: '=' : 間接参照のレベルが 'char *' と 'int' で異なって います。 >cl -nologo -W3 mmm.c mmm.c mmm.c(7) : warning C4013: 関数 'malloc' は定義されていません。int 型の値を返す外 部関数と見なします。 mmm.c(8) : warning C4047: '=' : 間接参照のレベルが 'char *' と 'int' で異なって います。 >gcc -Wall -c mmm.c mmm.c: In function 'main': mmm.c:7: warning: implicit declaration of function 'malloc' mmm.c:7: warning: incompatible implicit declaration of built-in function 'malloc ' >gcc -c mmm.c mmm.c: In function 'main': mmm.c:7: warning: incompatible implicit declaration of built-in function 'malloc ' 警告しないわけでもないのでスルーしてもいい問題だと思います。 > 私も含む初心者が混乱しないでしょうか? 確かにあなたは混乱したわけですから、しないとは言い切れないでしょう。 しかしながら初心者がおしなべて誤解するのか、 全員でなくても少なからぬ人が誤解するのかどうかは わたしにはわかりませんしあなたもわからないですよね(想像で言うのをなしにして)。 結論として記述を修正すべき問題であるとは わたしには思えません。

voronoi
質問者

お礼

回答ありがとうございます。#4での「レベル」云々の所は私に何かを暗示しているのかな、とは思っていましたが勉強になりました。 こう聞けばよかったと反省しています。 C89 において、 int *p; p=(int *)NULL; は、奇異に感じませんか? void* -> int* の自動型変換という意味においては、これも p=(int *)malloc(sizeof(int)); も私には同様に思えます。 それとも、C++に無理に合わせてmallocをキャストする場合でも、 p=NULL; とするんでしょうか。

voronoi
質問者

補足

jactaさんの方でも補足しましたが「私も含む初心者が混乱しないでしょうか?」は情報処理技術者試験の出題側に対してです。 どちらでもよいとのご指摘ですが、 int a=10; int b; b=(int)a; が問題文にあった場合(特に初心者は)奇異に感じませんか? 解答ならこれでも正解でしょうが、これだけ多くの方が受験している(この試験を期にCの勉強をはじめる人もいる)試験の問題では模範的な問題文が求められると思います。私の勉強不足なのでしょうが、なによりmallocでキャスト演算子を用いた際に何がメリットなのかが今もって私には理解できていません。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

> Wikipediaのmallocで調べてもC89のようなANSI規格ではキャストすべきでないとあり Wikipediaの文章ですが、わたしには「する必要がない」==してもしなくてもよい としか読めないのですが 「すべきでない」というのはどこで判断されたのでしょうか? Wikipedia 日本語版の記述は英語版のそれの翻訳のようなので原文を当たってみましたが | An explicit cast of malloc's return value is sometimes performed because malloc originally | returned a char *, but this cast is unnecessary in modern C code. キャストするなというニュアンスは読み取れないのですが。

voronoi
質問者

お礼

お礼をつけようと思いながら、遅れてしまいました。回答ありがとうございます。時間はかかると思いますが、ある程度勉強した上で他の回答にもお礼を書くつもりです。簡単な答えが得られる質問ではなかったことに驚いています。また、google での検索「情報処理技術者試験 C89」でこの質問がトップに来てしまうことを知り(11/7 2007)、足がすくんでいます。この回答自体への感謝としては、英語版のチェックということです。試しに altavista にて「malloc cast」(English only)で探したところ、cast が「悪い」or「困ったことになる」かどうかは何回もネットニュース等で質問があり、それに答える形で議論されているようです。検索結果も膨大であり、とても英文のすべてを読みこなすことはできていません。ただ、C89に限定した資格試験での問題文において、という条件での議論は海外にはないと思っています。

voronoi
質問者

補足

ご指摘ありがとうございます。次の理由からです。 wikipedia での脚注1に stdlib.h 忘れに対してキャストがあると困ったことになると書かれています。また、そこからたどれる C FAQ 日本語訳には、 「ANSI/ISO規格のCでは、こうしたキャストはもう必要ない。」 とあります。私も含む初心者が混乱しないでしょうか?

関連するQ&A