1 名前:デフォルトの名無しさん mailto:sage [2008/01/24(木) 14:52:45 ] このスレは標準C規格や規格に合致した移植性の高い記法・技法に関するスレです。 C言語初心者の初歩的な質問、GUIなどの標準Cではできない事の質問、 ソース丸投げ、宿題、書籍 などは専門の別スレッド↓があるのでそちらへ。 C言語なら俺に聞け(入門篇) Part 24 pc11.2ch.net/test/read.cgi/tech/1201083176/ 【初心者歓迎】C/C++室 Ver.47【環境依存OK】 pc11.2ch.net/test/read.cgi/tech/1200464091/ C/C++の宿題を片付けます 103代目 pc11.2ch.net/test/read.cgi/tech/1200318925/ 【書き込む前に】 ・まず問題を冷静に吟味してCの話か否かをはっきりさせてから質問しましょう。 ・質問する前には最低限検索を。 ・エラー(警告含む)が起きたのならばエラーメッセージを書きましょう。 【参考文献】 C FAQ 日本語訳 www.kouno.jp/home/c_faq/ Cプログラマ必読 ・プログラミング言語C(通称 K&R) www.amazon.co.jp/exec/obidos/ASIN/4320026926/250-7563469-9920244 【このスレのログ】 前スレ:pc11.2ch.net/test/read.cgi/tech/1190261457/ 他の過去ログ:nssearch.hp.infoseek.co.jp/clang/ 【このスレ住人としての心得】 わざとスレ違いあるいはごく低レベルな質問を繰り返して 流れを妨害する荒らしがいます。適当に誘導して放置してください。
641 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 18:55:23 ] inlineじゃなくて、static宣言された関数では?
642 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 18:55:54 ] >>641 C99でinlineが入ったんだよ。
643 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 19:18:31 ] inlineとstaticは同じ基準でインライン展開されるんですか。
644 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 19:19:07 ] よーわからんけど、extern inline が使えるってこと?
645 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 20:40:50 ] >>643 コンパイラ次第。 最適化レベルによって基準に差が出たり出なかったりする、なんてこともある。
646 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 20:41:26 ] >>644 inline 関数は常に内部リンケージ。
647 名前:デフォルトの名無しさん mailto:sage [2009/01/25(日) 02:27:15 ] 最適化をしない設定ではinlineをしていしても無効になるコンパイラもあるしね。
648 名前:デフォルトの名無しさん mailto:sage [2009/01/25(日) 05:53:01 ] 極端な話、今時inlineなんてregster程度の意味しかないと言ってもいい。
649 名前:デフォルトの名無しさん mailto:sage [2009/01/25(日) 10:58:41 ] register ・ C ではアドレスを取るとエラーになる(C++ では問題ない) ・ レジスタにするかどうかは 100% 無視される inline ・ 最適化なしでは static 関数も inline 関数もインライン化されない ・ 最適化低では inline 関数はインライン化されるが static 関数はインライン化されない ・ 最適化高では static 関数も inline 関数もインライン化される VC++ ではこんな感じだったと思う。 分岐する最適化レベルがいくらだったかは忘れた。
650 名前:デフォルトの名無しさん mailto:sage [2009/01/25(日) 16:20:26 ] >>649 ありがとうござます。 inlineはコンパイラによってインライン展開するかどうかは任意だと聞いてたんですけど、最適化を協力にすると任意じゃなくて必ず展開されるんですか それと、static関数は必ずインライン展開されるんですか。困った話ですね。 ということは、インラインとしては展開できない関数はないですね(つまり必ずマクロ関数みたくなる)。 inlineは最適化から出てきた機能ですが(関数専用の)テンプレートに近くなっているということでしょうか。
651 名前:デフォルトの名無しさん mailto:sage [2009/01/25(日) 16:23:03 ] >>650 いやいや、必ず展開されるという意味で書いたわけじゃない。 「インライン化されない」と書いた部分は「必ずインライン化されない」が、 「インライン化される」と書いた部分は「インライン化される可能性がある」の意味で書いた。
652 名前:デフォルトの名無しさん mailto:sage [2009/01/25(日) 16:44:33 ] 今のハードなら展開されようが、されまいがどうでもいいんじゃないの。 関数呼び出しコストなんて測定できないような時間(ナノ秒単位)で、普通は参照渡し。 組み込みとかセットボックスみたいだとハード資源が限られてるからループ内部とかでやれば多少効果はあるかもしれない。
653 名前:デフォルトの名無しさん mailto:sage [2009/01/25(日) 16:53:46 ] 画像処理とか激しいループは未だにあるもんだ。
654 名前:デフォルトの名無しさん mailto:sage [2009/01/25(日) 17:36:24 ] インライン展開することによる最適化も期待できるから >>652 は世間知らずだな としか思えない。
655 名前:デフォルトの名無しさん mailto:sage [2009/01/25(日) 17:44:03 ] static以外の関数でも最適化を上げればインライン展開されると思うよ。 外部リンケージ用に、通常関数版も用意されるはずだけど。
656 名前:デフォルトの名無しさん mailto:sage [2009/01/25(日) 17:49:42 ] まあそこらへんは規格に反しない限りはコンパイラが自由にやっていいことだからなぁ
657 名前:デフォルトの名無しさん mailto:sage [2009/01/25(日) 18:53:36 ] ファイルのリンケージを考えれば、どっちでもいいということですね。 オブジェクトファイルのサイズが増えても今のハード(携帯なども含む)なら微々たる物でしょうし。 気にしているのは、DLLみたく他人がつかうとき、それが関数のつもりがマクロみたく展開されてると不都合が生じるってことです。 関数ポインタのときとか。
658 名前:デフォルトの名無しさん mailto:sage [2009/01/25(日) 22:09:36 ] >>657 > 気にしているのは、DLLみたく他人がつかうとき、それが関数のつもりが > マクロみたく展開されてると不都合が生じるってことです。 > 関数ポインタのときとか。 意味わからん、inline の意味わかってるのか?
659 名前:デフォルトの名無しさん mailto:sage [2009/01/26(月) 00:18:35 ] 実行時の関数呼び出しとコンパイル時のインライン展開の違いはわかってる?
660 名前:デフォルトの名無しさん mailto:sage [2009/01/26(月) 00:20:50 ] inline 関数の中に malloc があったとき どっち側でメモリが確保されるのかは気にはなる。
661 名前:デフォルトの名無しさん mailto:sage [2009/01/26(月) 00:25:31 ] 何側と何側の話をしているんだ
662 名前:デフォルトの名無しさん mailto:sage [2009/01/26(月) 00:29:45 ] DLL側とDLLを使用している側
663 名前:デフォルトの名無しさん mailto:sage [2009/01/26(月) 00:31:33 ] 説明する気もうせる
664 名前:デフォルトの名無しさん mailto:sage [2009/01/26(月) 00:33:09 ] スレチだしな
665 名前:デフォルトの名無しさん mailto:sage [2009/01/26(月) 00:38:12 ] いいぞもっとやれ
666 名前:デフォルトの名無しさん mailto:sage [2009/01/26(月) 01:01:17 ] >>658-659 inline void func(); これを(*func)と関数ポインタで使うときどうなるんでしょうか? 例えばqsortに渡したりするときも、qsortみたいな関数ポインタを受け付けるAPIは実行時評価が目的の設計なので、 インライン展開されると不都合な気がするんですけど。 static関数もファイルスコープにおいて展開されるのは初耳だったんですけど、同じように実行時に不都合がありませんか?
667 名前:デフォルトの名無しさん mailto:sage [2009/01/26(月) 01:20:20 ] memcmp、strcmp、strncmpの返値だけど The memcmp function returns an integer greater than, equal to, or less than zero, accordingly as the object pointed to by s1 is greater than, equal to, or less than the object pointed to by s2. これはつまり、a > b > c だとしても、 memcmp(a, b, n)で100を返し、memcmp(a, c, n) で1を返してもいいんですよね? 0より大きいか小さいかだけが問題で。 accordinglyってのは、「大きい小さい等しい」に従うだけで 数値に従う必要はないですよね?
668 名前:デフォルトの名無しさん mailto:sage [2009/01/26(月) 01:21:53 ] うん。
669 名前:デフォルトの名無しさん mailto:sage [2009/01/26(月) 01:29:38 ] >>666 上で誰かが書いていたと思うけど、必要なら普通の関数のコードも併せて作るだけ。
670 名前:デフォルトの名無しさん mailto:sage [2009/01/26(月) 05:22:44 ] >>669 私だよん。 >>666 たまにはアセンブリ出力を眺めてみるもんだよ。 個々の行の意味が判らなくても、全体のボリュームとシンボルの位置でいろんなことが見えてくる。 >>667 その通り。実際、1,0,-1しか返さない処理系もあった筈だし、 最初に不一致だったバイトの差分を返す処理系もあった筈。
671 名前:デフォルトの名無しさん [2009/02/14(土) 05:16:14 ] ctype.h の関数を手持ちの char について使いたいときは、 char が符号付の場合を考慮して unsigned char にキャストしないといけないことを理解しました。 でも toupper() の戻り値 int は引数と同じ範囲の値を取るので、そのまま char に戻すことが できないように思います。 たとえば char 型の変数 c について、以下の条件をすべて満たすとき。 - (unsigned char)c == UCHAR_MAX - UCHAR_MAX > CHAR_MAX - toupper(UCHAR_MAX) == UCHAR_MAX ※変換なし c = toupper((unsigned char)c) という式は char には収まらない UCHAR_MAX を char に変換することになり、符号付整数のオーバーフローにより未定義動作と なってしまいそうです。 任意の char 型の値を大文字に変換して結果を char 型で得る方法として、 未定義動作も実装依存も回避した移植性のある方法はあるのでしょうか? 現実的には黙って char に変換すればいいように実装されてることが期待できるとは 思うのですが、ちょっと気持ち悪いです。
672 名前:デフォルトの名無しさん mailto:sage [2009/02/14(土) 07:29:40 ] なんか、とても杞憂な気がするるが、神経質にするならこうか? c= isalpha((unsigned char) c) ? toupper((unsigned char)c) : c;
673 名前:デフォルトの名無しさん mailto:sage [2009/02/14(土) 07:42:03 ] 気になってるのは、大文字アルファベットの表現がsinged charで負値になる環境とかだよね。 全く規格確認してないが、intの戻り値retについて、 CHAR_MINが負値でretがCHAR_MAXを超える場合、 自力でunsigned charをcharに変換するコードを書けば とりあえず解決するんじゃね? 1バイト文字の英数がASCIIで無い処理系ってあんま想定したこと無いから分からないけども、 「ASCIIじゃなきゃダメ」って記述は規格には無かった気がするなぁ。 詳しい人フォローよろしく。
674 名前:デフォルトの名無しさん mailto:sage [2009/02/14(土) 07:44:12 ] fgetc() なんかも同じだよね。とりあえず EOF をチェックして、それが済んだら char として 扱いたいんだけど、変換できるの?っていう。
675 名前:デフォルトの名無しさん mailto:sage [2009/02/14(土) 09:13:41 ] >>671 そもそも規格上は unsigned char を signed long するだけでだめなケースがあるから > 未定義動作も実装依存も回避した移植性のある方法はあるのでしょうか? の答えは「ない」だよ。 >>673 > 「ASCIIじゃなきゃダメ」って記述は規格には無かった気がするなぁ。 汎用機用の C言語処理系で文字コードが EBCDIC のものがある。
676 名前:デフォルトの名無しさん mailto:sage [2009/02/14(土) 09:45:53 ] >>671 toupper に正しく小文字を与えれば、正しく大文字になるでしょ? それ以上のものはないよ UCHAR_MAXを toupper に与えたらUCHAR_MAXが返るだろうけど、 そもそもなんでその結果を signed char にキャストするの? UCHAR_MAXを与えるということは signed char じゃなかったんでしょ? >>674 toupper()やfgetc()の結果をcharと比較したい場合、 charに変換して戻すんじゃなくて、比較先をintにするのが普通では? int c = fgetc(); if ( c == 'a' ){ … とか
677 名前:デフォルトの名無しさん mailto:sage [2009/02/14(土) 10:11:11 ] >676 明示的に UCHAR_MAX を与えるわけじゃなくて、unsigned char に変換すると UCHAR_MAX になる値が char としてあった場合に、unsigned char にキャストしてから toupper に与えた場合とか。 > toupper()やfgetc()の結果をcharと比較したい場合、 比較ならいいけど、char に代入したくなったらどうするの? 例えば、文字列中の小文字を全て大文字に変換する関数 strupper(char*) を定義しようとかいう場合。 やっぱ >672 のように書けってことだろうか。
678 名前:デフォルトの名無しさん mailto:sage [2009/02/14(土) 10:13:56 ] >>676 > toupper()やfgetc()の結果をcharと比較したい場合、 単純比較なんて誰も悩んでないと思うが。 配列に入れて、printf() で出力したい時とか考えつかないわけ?
679 名前:デフォルトの名無しさん mailto:sage [2009/02/14(土) 11:51:23 ] signed char が -127〜127 で文字コードが 0〜255 の環境なら、 処理系は char を unsigned char 固定で扱うようになっているんじゃないのか? じゃないと char が文字コードを収める事ができるという 最低条件をクリアできないじゃん。
680 名前:デフォルトの名無しさん mailto:sage [2009/02/14(土) 11:56:18 ] >>677 >>unsigned char にキャストしてから toupper に与えた場合とか。 だから、なんでキャストするの? 入力が signed char なら signed char → int に変換されても UCHAR_MAX はありえない。 入力が unsigned char なら UCHAR_MAX はありうるけど、それは 変換前も変換後も UCHAR_MAX のままでしょ
681 名前:デフォルトの名無しさん mailto:sage [2009/02/14(土) 13:17:25 ] >>680 ふふ、
682 名前:デフォルトの名無しさん mailto:sage [2009/02/14(土) 13:24:25 ] 一連のレスで、UCHAR_MAX は一例だと思うよ。 問題は、signed charで表せないのにunsigned charで表せる文字 ではなくて、signed charで負の値になるunsigned charの文字 ではなかろうか。このような文字を安全に unsigned char から signed charに変換する標準的な方法が無いこと。 もう一つは、toupperの引数は非負が仮定されているので、 toupperの引数は(intだけど)数値としては実質的にunsigned char を渡す事になる。 この二つの問題が絡み合っているのね。
683 名前:デフォルトの名無しさん mailto:sage [2009/02/14(土) 15:38:04 ] >680 unsigned char 範囲の値を渡せって規格で要求されてるから。 > 9899:1999 7.4 > The header <ctype.h> declares several functions useful for classifying and mapping > characters. In all cases the argument is an int, the value of which shall be > representable as an unsigned char or shall equal the value of the macro EOF. If the > argument has any other value, the behavior is undefined.
684 名前:680 mailto:sage [2009/02/14(土) 22:52:12 ] >>683 その文章は知ってるよ。 でもそれは toupper の引数は unsigned char でキャストしろ、って意味.じゃない signed char を指定した場合で -2 〜 -128 の場合は undefined だよ、って言ってるだけ (EOFが-1として)
685 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 00:14:28 ] 実際死ぬケースもあったな。マイナス与えると。 日本語扱うとよくある。
686 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 00:16:35 ] > 未定義動作も実装依存も回避した移植性のある方法はあるのでしょうか? 最初っから全部unsigned charにしとけでイナフ
687 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 00:23:38 ] >>679 についてはどうなんだ?
688 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 01:03:33 ] >>684 未定義動作を回避するのに、 unsigned char にキャストするほかにどうすんの?
689 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 01:06:46 ] >>679 basic character set に無い処理系依存の拡張文字の char としての値について、 符号も含めて規定は無いから、負の値が拡張文字に対応しても問題なさそう。 6.2.5 Types p3 > An object declared as type char is large enough to store any member of the basic > execution character set. If a member of the basic execution character set is stored in a > char object, its value is guaranteed to be nonnegative. If any other character is stored in > a char object, the resulting value is implementation-defined but shall be within the range > of values that can be represented in that type.
690 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 01:11:07 ] >684 じゃ、 > signed char を指定した場合で -2 〜 -128 の場合 はどうすれば? 範囲チェックして toupper には渡すなって主張? >687 0〜255 だというなら確かにそうかもね。 > 9899:1999 6.2.5/3 > If a member of the basic execution character set is stored in a > char object, its value is guaranteed to be positive. If any other character is stored in a > char object, the resulting value is implementation-defined but shall be within the range > of values that can be represented in that type. という記述を見ると basic execution character set 以外なら負値も認めているように読めるけど、 後は実装依存の闇の中、かな。
691 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 01:22:17 ] int toupper(int c);
692 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 01:22:20 ] なるほど・・・。 完全に環境無依存のコードは無理っぽいね。
693 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 01:55:08 ] 卓上の妄想なら不可能だが、現実的にはみんなやってるだろ
694 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 01:59:26 ] なんで文字を扱ってるのに符号を気にしなきゃいけないんだよC言語のバカ!
695 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 02:11:42 ] char の符号が未規定なのって どんなケースを想定してのことなのだろうか。 符号つきの文字コードがあったらいけないから?
696 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 02:18:33 ] 8 bit 符号付でも ASCII の表現には十分だから実装任せで良いよね。 っていう話だと思う。 C++ では char を受けて char を返す toupper/tolower があるから、今さら 規格を変更する(変更を検討する)モチベーションも無いだろうしなぁ。
697 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 04:13:14 ] リアルタイムの人間じゃないけど。 規格がまとまる前にsigned, unsigned両方の実装が出ていたから、 というのが最大の理由だったと思う。 そこから先は>>696 のとおり。
698 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 09:07:58 ] int は、ディフォルトで signed なのに、char のディフォルトを決めなかったのが 敗因だと思う。 まあ今時だとメモリも潤沢だからわざわざ char に詰め込もうなんて思わないけど、 当時だと short short int の役目もあったのかもしれないな。
699 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 10:18:39 ] MS-cがオプションでcharをアンサインドにできる仕様だったからねぇ。 intとは事情が違うね。
700 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 10:52:13 ] lattice-c(2のころ)はunsignedだったっけ?
701 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 11:12:02 ] >>688 出力を未定義にしたくないなら、未定義にならない引数を与えろってこと。 toupper呼ぶ前に、入力文字の範囲チェックしないってことは無いだろう普通 それを unsigned char へのキャストで済ませられたらいいな、と 考えたのだろうけどそれじゃダメって話
702 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 11:29:04 ] >>701 範囲をどうチェックするするべきだと言うの? チェックで範囲外だとわかったらどうしろっていうの? toupper() に渡さないと大文字にできんのだが。
703 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 12:16:42 ] 馬鹿なの? 大文字にしたければ小文字を渡せよ if( isascii(c) && islower(c)) c = toupper(c); これを c = toupper((unsigned char)c); とすると規格上不定になります(;_;)とか言ってるから キャストするからだろ馬鹿、って言ってるんだ
704 名前:デフォルトの名無しさん [2009/02/15(日) 12:23:28 ] 大馬鹿なの? toupper の前に islower なんかいらねーよ
705 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 12:23:30 ] >>703 標準の範囲で実装依存せずにどうするかって話なのに、 非標準の isascii() とか入れてみたり勝手に ASCII 大文字だけに要求を絞ったり、 ギャグでやってるのか?
706 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 12:37:08 ] いいえ、ボールギャグです。
707 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 15:08:42 ] で、実際のところa-z|A-Zが符号付き表現で負になることはありえるの?
708 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 15:11:34 ] それは知らないけど、 "C" locale以外ではa-z|A-Z以外でもislower/isupperが真になるということなら有り得ると思う。
709 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 15:12:31 ] 真になるってどういう事だよ。
710 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 15:13:04 ] あ、空目してた。ごめんよ。
711 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 15:14:32 ] 結局は>>686
712 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 16:26:35 ] >>707 そいつらは basic execution character set に入ってるから char 型の符号の有無に かかわらず負にならないことが保証されてる。 ( >689,690 が引用してる箇所参照)
713 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 17:39:56 ] >>712 素朴な疑問、EBCDIC な文字コードの処理系の場合どうなるんだ?
714 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 18:09:27 ] >>713 文字コードは関係ない。( >689,690 が引用してる箇所参照)
715 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 18:30:21 ] >>714 EBCDIC って 8bit だと MSB たってんじゃん, char 9bit 以上で実装しろって話?
716 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 19:33:50 ] >>699 MS-C はシフトJIS でトラブル奴が多いからそういうオプションを サポートしただけだろ。
717 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 19:35:12 ] >>715 EBCDIC のコードを 8 bit char の値に使うなら char 型を unsigned にするしかないということ。
718 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 20:08:24 ] >>717 fgetsやprintfやstrcmpなどの型も全部変更するの?
719 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 20:11:42 ] >>718 きっと何か勘違いしてると思うけどそれらの関数でどういう問題が起きると思うの?
720 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 21:19:58 ] >>718 unsigned charにするんじゃなくて、 char自体を符号無しにするってことだろ。
721 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 22:46:22 ] >>717 ああ、それなら納得 「>>712 char 型の符号の有無にかかわらず負にならない」 てな、書き方はやめてほしかった
722 名前:デフォルトの名無しさん mailto:sage [2009/02/26(木) 04:13:51 ] 今現在、charをsignedで使う意味ってあるのかな。
723 名前:デフォルトの名無しさん mailto:sage [2009/02/26(木) 15:09:34 ] >>722 charを文字ではなく数値として使うこと考えれば。 intへの昇格も考えなきゃならんし。
724 名前:デフォルトの名無しさん [2009/03/01(日) 00:55:23 ] C言語なら俺に聞け(入門篇) Part 45 pc11.2ch.net/test/read.cgi/tech/1235044065/l50 こっちが埋まったんで、とりあえずageておく。
725 名前:デフォルトの名無しさん mailto:sage [2009/03/01(日) 03:16:58 ] あのグダグダを持ち込まれても困るんだが
726 名前:デフォルトの名無しさん mailto:sage [2009/03/01(日) 21:51:47 ] ネタ切れ? じゃぁ 問題: int i, j; int main() { i = 1; j = i++ * i++; printf("%d, %d\n", i, j); } このプログラムを実行するとどうなるか? どうなるべきか? 結果もしくは挙動を推測せよ。 (includeとかmainの型なんかは、適宜補え。文句言うな)
727 名前:デフォルトの名無しさん mailto:sage [2009/03/01(日) 22:17:00 ] jの右辺が未定義動作だから何が起こるかわからない 「3,6」と表示されるかもしれないし「3,9」と表示されるかもしれないし 「5196823, -98600289」と表示されるかもしれないし「qあwせdrftgyふじこlp;」と表示されるかもしれないし プログラムが異常終了するかもしれないしOSがクラッシュするかもしれないし PCが火を噴くかもしれないし地球が爆発するかもしれないし鼻から悪魔が出てくるかもしれない 常識だと思うが、今更どうした
728 名前:デフォルトの名無しさん mailto:sage [2009/03/01(日) 22:54:37 ] mainが値を返してないからコンパイルできない
729 名前:デフォルトの名無しさん mailto:sage [2009/03/01(日) 22:56:00 ] C99なら可だが
730 名前:デフォルトの名無しさん mailto:sage [2009/03/02(月) 11:15:52 ] 鼻から悪魔は無いな、たぶん。
731 名前:デフォルトの名無しさん mailto:sage [2009/03/02(月) 20:09:45 ] 出てきてからじゃ遅いんだよ、出てきてからじゃ。
732 名前:デフォルトの名無しさん mailto:sage [2009/03/02(月) 21:31:38 ] ネタ切れ? じゃぁ 問題: int a[32], b[32], *p = a; if (p < b || b + 32 <= p) printf("悪魔が出る。"); else printf("いずれにせよ悪魔が出る。"); このプログラムの断片について議論して。前後は適当に補ってね。
733 名前:デフォルトの名無しさん mailto:sage [2009/03/02(月) 21:50:06 ] どこにも悪魔は出ないだろ・・・ b + 32 は脱参照しなければ合法だし ポインタは順序付け可能だ(どういう順序になるかは未規定だが)
734 名前:デフォルトの名無しさん [2009/03/02(月) 21:55:05 ] p < b の大小関係が未規定ゆえ、結果が未定義となる
735 名前:デフォルトの名無しさん mailto:sage [2009/03/02(月) 22:14:11 ] どういう順序になるかは未規定だが 順序付け可能とは定義されてるよ
736 名前:デフォルトの名無しさん mailto:sage [2009/03/02(月) 22:14:47 ] 結果は未定義じゃなくて未規定 少なくとも鼻から悪魔は出ない
737 名前:デフォルトの名無しさん mailto:sage [2009/03/02(月) 22:17:06 ] When two pointers are compared, <ばっさり省略> In all other cases, the behavior is undefined.
738 名前:デフォルトの名無しさん [2009/03/02(月) 22:24:43 ] 未規定の動作が生じうる可能性のうちのいずれかに依存したコードには可搬性があるというのか?
739 名前:デフォルトの名無しさん mailto:sage [2009/03/02(月) 22:25:46 ] ばっさり省略しすぎだろwww 同じ型なら比較可能だ
740 名前:デフォルトの名無しさん mailto:sage [2009/03/02(月) 22:28:54 ] >>739 俺も今6.5.8をみていたところだが > 同じ型なら比較可能だ これはどこに書いてある?
741 名前:デフォルトの名無しさん mailto:sage [2009/03/02(月) 22:29:03 ] >>739 同じ型でも違うオブジェクトであればだめだよ。
742 名前:デフォルトの名無しさん mailto:sage [2009/03/02(月) 22:40:59 ] ああ、Cだとダメなのか。 C++だといいからCでもいいのかと思った。
743 名前:デフォルトの名無しさん mailto:sage [2009/03/03(火) 21:56:44 ] >742 C++ でも駄目だろ、と思ったけど未規定なのな。 そして std::less とかだと全順序保証、と。
744 名前:デフォルトの名無しさん mailto:sage [2009/03/04(水) 00:43:13 ] Cだとポインタを二分探索木で管理するには その先の値を見るしかないのか。 その先の値の順番に特に意味が無くても。
745 名前:デフォルトの名無しさん mailto:sage [2009/03/04(水) 00:54:51 ] >>744 先の値の順番に意味がなかったらなにを基準に木構成する気だ
746 名前:デフォルトの名無しさん mailto:sage [2009/03/04(水) 11:51:54 ] ポインタのアドレスそのもので探索する?
747 名前:デフォルトの名無しさん mailto:sage [2009/03/04(水) 13:05:25 ] 連続メモリ空間上のポインタなら二分木で管理するまでもないし そうでないなら比較の保障がない以前に意味がないだろ
748 名前:デフォルトの名無しさん mailto:sage [2009/03/04(水) 13:05:56 ] ×空間上のポインタ ○空間上へのポインタ
749 名前:デフォルトの名無しさん mailto:sage [2009/03/04(水) 22:25:15 ] >>744 この世にはデリファレンスできないポインタも存在するわけだが。
750 名前:デフォルトの名無しさん mailto:sage [2009/03/04(水) 23:54:43 ] int にキャストして比較すれば良いんじゃない
751 名前:デフォルトの名無しさん mailto:sage [2009/03/04(水) 23:56:45 ] そしてオーバーフローするんですね、わかります
752 名前:デフォルトの名無しさん mailto:sage [2009/03/05(木) 10:58:14 ] >>750 その比較が意味のあるものとなる保障はない。 それに>>751 がいうようにintじゃだめだろう。
753 名前:デフォルトの名無しさん mailto:sage [2009/03/05(木) 23:11:20 ] ポインタをポインタと同じサイズの整数型に変換可能な事は保証されてるから uintptr_t 使うならええんでないかい?
754 名前:デフォルトの名無しさん mailto:sage [2009/03/05(木) 23:14:22 ] それなら問題ないよ。
755 名前:デフォルトの名無しさん mailto:sage [2009/03/21(土) 12:06:23 ] double v; としてvがnanやinfinityであるかを判定するにはどうやるんでしょうか? 標準ライブラリ見てもそのような関数が用意されてないので困っています。 v!=vでnanなのは分かっているのですが、他に方法はないのでしょうか。 それと、実数のときと複素数のときの判定方法を教えてください。 一応GCCです。
756 名前:デフォルトの名無しさん mailto:sage [2009/03/21(土) 12:33:17 ] >>755 -std=c99 でisnan、isinfあたり。
757 名前:デフォルトの名無しさん mailto:sage [2009/03/21(土) 13:06:48 ] c99にすれば用意されているのですが、コンパイラ・オプションで指定しないと標準ではinf, nanは判定できないって事ですか?
758 名前:デフォルトの名無しさん mailto:sage [2009/03/21(土) 13:20:38 ] >>757 いちおう、 C99 は「標準」だよ。 gcc のデフォルトは C99 じゃないけど、拡張の一部として isnan, isinf は 使えたりするかもしれない。っていうか、試せばいいよ。
759 名前:デフォルトの名無しさん mailto:sage [2009/03/21(土) 13:40:11 ] そういえばinfinityの判定はやったことなかったけど、今までみんなはどうやってたんだろう・・
760 名前:デフォルトの名無しさん mailto:sage [2009/03/21(土) 13:42:21 ] >>756 に書いてあるじゃんw
761 名前:デフォルトの名無しさん mailto:sage [2009/03/21(土) 13:54:44 ] 古いAPIを読んでたのでなかったんですが、今後はコーディングするときはC99準拠で必ずやることにします。
762 名前:デフォルトの名無しさん mailto:sage [2009/03/21(土) 14:02:39 ] 昔も標準でなかっただけで普通にあった。 isinfinity()の環境もあった。 > 今後はコーディングするときはC99準拠で必ずやることにします。 素晴らしいです。
763 名前:デフォルトの名無しさん mailto:sage [2009/03/22(日) 10:12:15 ] restrictとか可変長配列とか勝手に使うと迷惑になることもあるから気を付けろよ 個人ならいいけど
764 名前:デフォルトの名無しさん mailto:sage [2009/03/22(日) 14:04:37 ] >>763 kwsk
765 名前:デフォルトの名無しさん mailto:sage [2009/03/23(月) 13:18:20 ] >>764 c99ではrestrictは予約語。iccだとオプションを指定すればc++でも使える。
766 名前:デフォルトの名無しさん mailto:sage [2009/03/23(月) 16:59:58 ] ところで今の規格準拠コンパイラは複素数のinf, nanを判定できるのか?
767 名前:デフォルトの名無しさん mailto:sage [2009/03/28(土) 01:41:09 ] Cに複素数なんて概念あったっけ?
768 名前:デフォルトの名無しさん mailto:sage [2009/03/28(土) 05:50:48 ] >>767 c99
769 名前:デフォルトの名無しさん mailto:sage [2009/03/28(土) 06:37:18 ] いい加減、このスレの参加資格に、C99の規格書を読むことを入れとこうぜ
770 名前:デフォルトの名無しさん mailto:sage [2009/03/28(土) 09:36:52 ] まあseclan.dll.jp/c99d/ くらいは参照した方がいいかと。
771 名前:デフォルトの名無しさん mailto:sage [2009/03/28(土) 09:48:37 ] 確かに2009年にもなってC99を知らんのはこのスレ的にはお断りだ Cを知らないに等しい
772 名前:デフォルトの名無しさん [2009/03/28(土) 09:50:19 ] 旧規格もそうと断ったうえでなら可だろ 事実上まだ現役だし
773 名前:デフォルトの名無しさん mailto:sage [2009/03/28(土) 10:24:27 ] C99を実際には使わなくても 知っていなくてはこのスレにいる資格は無いな
774 名前:デフォルトの名無しさん [2009/03/28(土) 10:34:44 ] まあ複素数は置いといて、何かを知らないことをもって C99 を知らないことにされたら 資格者ほとんどいないんじゃね?
775 名前:デフォルトの名無しさん mailto:sage [2009/03/28(土) 10:49:42 ] 今規格をあたろうとすると必然的にC99になるからそうでもないと思うが
776 名前:デフォルトの名無しさん [2009/03/28(土) 10:58:12 ] それなら C99 を「知っている」のではなく「規格票にアクセスできる」ことが資格というべきではないか?
777 名前:デフォルトの名無しさん [2009/03/28(土) 10:59:29 ] # 今日はここまで、遊びに出かける
778 名前:デフォルトの名無しさん mailto:sage [2009/03/28(土) 11:00:14 ] でも最低でも>>770 くらいのことは知っておいて欲しい
779 名前:デフォルトの名無しさん mailto:sage [2009/03/28(土) 12:46:04 ] コンパウンドリテラルとか便利だけどね。 ただどれがGCC拡張か規格機能なのかよく分からないことがよくある。 それよか、API文章をC99対応にしないと広まらないだろう。 とくにMSDNが率先してC99に対応しないとGNU方面の人たちだけになるんじゃないか? MSはカオスだしそのうち空中分解しそうだけど。
780 名前:デフォルトの名無しさん mailto:sage [2009/03/28(土) 13:42:40 ] >>779 > MSはカオスだしそのうち空中分解しそうだけど。 突然それまでの話と関係ない一言を最後に入れるあたり、天声人語かと思った
781 名前:デフォルトの名無しさん mailto:sage [2009/03/28(土) 13:58:20 ] コンパウンドリテラルはC++にも欲しい
782 名前:デフォルトの名無しさん mailto:sage [2009/03/28(土) 14:24:48 ] コンストラクタ主義と コンパウンドリテラルは合わない。 デフォルトコンストラクタのみなら、 リスト初期化子の記法で何とかなりそうではあるけど。
783 名前:デフォルトの名無しさん mailto:sage [2009/03/28(土) 14:28:01 ] 配置newで乗り切る。
784 名前:デフォルトの名無しさん mailto:sage [2009/03/28(土) 15:09:28 ] 配列のコンパウンドリテラルの代わりになるものは C++0xにあるんだっけ?
785 名前:デフォルトの名無しさん mailto:sage [2009/03/28(土) 15:36:26 ] まだバタバタしてますがこれ。 Initializer List www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2672.htm initializer-list constructorってのがあって(以下上の提案参照
786 名前:デフォルトの名無しさん mailto:sage [2009/03/28(土) 21:27:50 ] C90に準じていても、それをゆるさない車載標準規約であるMISRA-C。 マジでうざい規約です・・・
787 名前:デフォルトの名無しさん mailto:sage [2009/03/28(土) 22:21:01 ] >>785 かなりバタバタしてる雰囲気がするねw
788 名前:デフォルトの名無しさん mailto:sage [2009/03/29(日) 09:28:51 ] union { char a[4]; int i } u; というような共用体があったとき、 u.a[0]〜u.a[3]に代入した後、それをu.iで参照するのは未定義でしょうか? 6.5のeffective typeの説明を読む限りではそうなってしまいそうなんですが。 未定義でないとすると、その根拠は規格のどの辺で規定されています?
789 名前:デフォルトの名無しさん mailto:sage [2009/03/29(日) 10:43:24 ] The effective type of an object for an access to its stored value ... ってとこ? どこに未定義って書いてある?
790 名前:デフォルトの名無しさん [2009/03/29(日) 11:11:42 ] > 4. 規格合致性 > この規格では,このほかに,用語“未 > 定義の動作”を使うことによるか又は動作の明示的な定義を与えないことによって未定義の動作を示すこ > ともある。
791 名前:デフォルトの名無しさん mailto:sage [2009/03/29(日) 11:13:29 ] >>788 参照はして構わない。値は未定義。
792 名前:デフォルトの名無しさん mailto:sage [2009/03/29(日) 12:31:08 ] 多くの実装ではこちらが期待したとおりのビット列として読み出すことができる しかし規格上は、ある型で与えた値を別の型で読み出せることは保障していない 結論:自己責任
793 名前:デフォルトの名無しさん mailto:sage [2009/03/29(日) 12:49:17 ] >>792 実装の説明には書かれているものなのかな? たとえば、gccとか。
794 名前:デフォルトの名無しさん mailto:sage [2009/03/29(日) 12:54:16 ] 規格で保証してないことを保証してるなら、書いてあることもある。 gccでは保証してないどころか、予想だにしない結果になるんじゃなかったっけ? -O2 とかだと。
795 名前:デフォルトの名無しさん mailto:sage [2009/03/29(日) 13:04:43 ] いやalignとかpaddingとかオプションで指定できるし。> gcc それにconfigureで確かめたり、実行時にassertしたりできるでしょ。 ただ何がやりたいのか不明だけど、勝手に想像すると、今時のマナーでは、 #include <stdint.h> union { uint8_t a[4]; int32_t i; } u; とするんじゃないのかな。
796 名前:デフォルトの名無しさん mailto:sage [2009/03/29(日) 13:08:39 ] 何が今時なのか分からん。
797 名前:デフォルトの名無しさん mailto:sage [2009/03/29(日) 13:12:49 ] sizeof(int) == 4と仮定しない方がいい→今時
798 名前:デフォルトの名無しさん mailto:sage [2009/03/29(日) 13:13:10 ] >>796 サイズが同じなら、予想した動作になるってことかな?
799 名前:デフォルトの名無しさん mailto:sage [2009/03/29(日) 13:13:53 ] charとuint8_tが等価なのも今時なのか?
800 名前:デフォルトの名無しさん mailto:sage [2009/03/29(日) 13:18:32 ] 粘着乙
801 名前:デフォルトの名無しさん mailto:sage [2009/03/29(日) 13:54:11 ] char だと 0x80 の値が使えないかもしれないジャマイカ
802 名前:デフォルトの名無しさん mailto:sage [2009/03/29(日) 13:57:04 ] charが9ビット以上である可能性がな・・・
803 名前:デフォルトの名無しさん mailto:sage [2009/03/29(日) 13:57:58 ] >>801 いや、もともとcharで切ってたならcharとしての使い方しかしないでしょ。 なんでuint8_tにするの?ってことなんだけど。
804 名前:デフォルトの名無しさん mailto:sage [2009/03/29(日) 14:11:03 ] >>803 何言っているか意味がわからんが? > charとしての使い方しかしないでしょ。 ここはC++スレじゃないぜ?
805 名前:デフォルトの名無しさん mailto:sage [2009/03/29(日) 18:55:14 ] C++が何で関係あるのか分からんが もともとcharで切ってる事自体、 本当によく考え抜かれたものか怪しいことは確か
806 名前:デフォルトの名無しさん mailto:sage [2009/03/29(日) 19:05:34 ] 結局 >>788 批判ですかw
807 名前:デフォルトの名無しさん mailto:sage [2009/03/29(日) 20:06:01 ] C++が何で関係あるのか分からんやつは答えなくてよろし
808 名前:デフォルトの名無しさん mailto:sage [2009/03/29(日) 21:02:11 ] みなさま、ご回答ありがとうございます。 intとcharは例が悪かったかも知れませんが、 相談の主旨は union U { t1 m1; t2 m2; } u; (ただしt1とt2はcompatibleでない) に対して、u.m1に書き込んだ値をu.m2で読み込んだときの 言語仕様についてでした。 例だと、 uの表すobjectのeffective typeはunion U u.m1の表すobjectのeffective typeはt1 u.m2の表すobjectのeffective typeはt2 になるわけですが、u.m1とu.m2の表すobjectが同じものと考えれば、 1つのobjectがt1とt2という2つのeffective typeを持つ。 だから、u.m1に書き込んだ値をu.m2で読み込むのは許される。 ただし、読み込まれる値については未規定である。 という理解でよいのでしょうか?
809 名前:デフォルトの名無しさん mailto:sage [2009/03/29(日) 22:29:36 ] そだね。
810 名前:デフォルトの名無しさん mailto:sage [2009/03/29(日) 22:32:37 ] CとC++でcharの扱いが全く違うことは、 まあスレ違いなんで知らなくてもいいけど、 Cのcharがintegral typeでintegral promotionの対象、 ANSIでも"as is"が認められているだけってことは知っておかないと。
811 名前:デフォルトの名無しさん mailto:sage [2009/03/29(日) 23:44:30 ] >>809 適当なことを言わないように
812 名前:デフォルトの名無しさん mailto:sage [2009/03/31(火) 08:00:10 ] Cの言語仕様というと、俺はいまだにK&Rなんだが。
813 名前:デフォルトの名無しさん mailto:sage [2009/04/01(水) 22:59:50 ] >>788 どうせおもいっきり環境依存なんだから、 面倒なことしないで、 char a[4]; にセットして *(int*)a で読んじゃえ。
814 名前:デフォルトの名無しさん mailto:sage [2009/04/01(水) 23:08:51 ] >808 > になるわけですが、u.m1とu.m2の表すobjectが同じものと考えれば、 とあるが、共用体のメンバに対応するオブジェクトはすべて同じなのか? 大きさも型も違うのに。 むしろ同じアドレスだけど、オブジェクトは別と考えるのが自然だと思う。
815 名前:デフォルトの名無しさん mailto:sage [2009/04/01(水) 23:15:21 ] static_assert(期待通りの値が入ってるかどうか) をどっかに入れておけばいい。
816 名前:デフォルトの名無しさん mailto:sage [2009/04/01(水) 23:15:40 ] >>813 strict aliasing rule違反じゃね?どうなの?
817 名前:デフォルトの名無しさん mailto:sage [2009/04/01(水) 23:30:28 ] >>816 大丈夫なCPUとダメなCPUがある。 x86系は大丈夫。 逆の方が適用可能な範囲が広いか。 int a; を ((char*)&a)[0〜3] で書く。
818 名前:デフォルトの名無しさん mailto:sage [2009/04/02(木) 02:58:14 ] >>816 違反。 逆に int a; を用意して (char*)&a 経由でセットし、その後 a を読むのなら OK 。
819 名前:デフォルトの名無しさん mailto:sage [2009/04/05(日) 00:23:29 ] なんでC言語には累乗計算の為の演算子がないのですか?
820 名前:デフォルトの名無しさん mailto:sage [2009/04/05(日) 00:43:38 ] 累乗計算命令を積んでるCPUが少ないからだ