【初心者お断り】ガチ ..
[2ch|▼Menu]
480:デフォルトの名無しさん
08/11/20 23:25:48
>>475
アマチュアの方ですか?
CはC++みたく引数までシグネチャーに含んでくれないので、
型チェックはコンパイル頼みになるのです。
引数なしの関数をチェックさせるために(void)って書くんですよ。

まぁあなたみたいに一人でオナニープログラム書いている人には
関係ないでしょうが。

481:デフォルトの名無しさん
08/11/20 23:26:38
>>473
使い分ける必要のある環境なら
main のあるソースをコンパイルする時に
自動的にそれに対応したスタートアップを追加するか、
あるいはリンカが main によってリンクするスタートアップコードを変えるか、
そういう実装になるはずだろう。

482:デフォルトの名無しさん
08/11/20 23:27:20
>>471
「普通の関数でも 引数指定部分のvoid は好まない」とは一言ももうしあげておりません。

483:デフォルトの名無しさん
08/11/20 23:27:37
>>478
まず、int main() { } の () は don't care ではなく void だ。規格上は。

484:デフォルトの名無しさん
08/11/20 23:27:46
>>478
>それに、スタートアップで引数をスタックに積んでいる以上、
>main() の場合は do not care のほうが適当かと。
ダウト。
引数をスタックに積むとは限らない。
処理系依存。

485:デフォルトの名無しさん
08/11/20 23:28:58
>>472
言葉が足りませんでしたね。
呼び出し側で引数を指定しているのに、コール先で引数なしとすることはないと思います。
これが呼び出し側:スタートアップ、コール先:main() であっても同じなのではないでしょうか?

486:デフォルトの名無しさん
08/11/20 23:29:22
>>485
ダウト。
常に呼び出し側で引数を指定しているとは限らない。

487:デフォルトの名無しさん
08/11/20 23:31:19
>>484
ん、広く範囲をとれば、それはそういうことになるとは思います。確かに引数をスタックに積むとはかぎりらないでしょうね。

488:デフォルトの名無しさん
08/11/20 23:31:22
型チェックってのは1つ以上の引数を渡した時に、間違った型として扱わないために必要なのであって
もともと引数取らない関数にとってはどうでもいいことです
だいたい引数取らない関数に引数なんか渡したら誰だって間違いと気付きます

ちなみにC++が引数なし関数までシグネチャに含むのはデフォルト引数があるからです

489:デフォルトの名無しさん
08/11/20 23:32:18
>>483
詳説を希望いたします。

490:デフォルトの名無しさん
08/11/20 23:32:50
>>485
>呼び出し側で引数を指定しているのに、
>コール先で引数なしとすることはないと思います。
ダウト。
それはあなたの思い込み。
言語仕様上そういうことが可能ならば、間違いは必ずおきます。
プロならばそれを回避しようとするのは当然。

491:デフォルトの名無しさん
08/11/20 23:32:53
>>488
コンパイラは間違いに気づきません。
コンパイラが気づかなかった事により、人間も気づかないかもしれません。
例えば引数の数を変えた時とか。
そもそも引数の数によって引数チェックが必要か必要ないかが変わることこそ気持ち悪い。

492:デフォルトの名無しさん
08/11/20 23:33:47
>>489
>>462

何度も同じ事を言わせるな。

493:デフォルトの名無しさん
08/11/20 23:33:56
引数をスタックに積まない実装など見たことがありません
今までに存在したとも思えないし、これから登場することも考えられません
(ネタやお遊びで作った実用性のない環境は知りませんよ)

規格の無意味な汎用性への配慮の産物がint main(void)という醜悪な構文なのです

494:デフォルトの名無しさん
08/11/20 23:34:04
>>488
>だいたい引数取らない関数に引数なんか渡したら誰だって間違いと気付きます
んー、コンパイル単位を別にとれば、問題なくコンパイル/リンク可能で、かつ、大概の環境では問題もないのですが。

495:デフォルトの名無しさん
08/11/20 23:35:04
>>488
>ちなみにC++が引数なし関数までシグネチャに
>含むのはデフォルト引数があるからです
ダウト。
C++にはオーバーロードがあるからです。
知ったかすんな

496:デフォルトの名無しさん
08/11/20 23:35:23
>>492
これは申し訳ない。調べておきます。

497:デフォルトの名無しさん
08/11/20 23:36:16
>>493
ヒント:ニンテンドーDS

498:デフォルトの名無しさん
08/11/20 23:36:57
>>493
レジスタ渡しとかも普通にするだろ。

499:デフォルトの名無しさん
08/11/20 23:37:06
>>491
そもそも間違って渡したから何だというのでしょう
引数に名前は付いてないので関数からは手出しできません
だから何かを壊すことはありません
せいぜい値渡しの無駄なコピーが何回か増えるだけです
型チェックのコストの方が高いという判断はありうることです

500:デフォルトの名無しさん
08/11/20 23:37:54
なんだか釣りにしか見えなくなってきたな

501:デフォルトの名無しさん
08/11/20 23:38:05
>>499
やっぱ引数欲しいや、って増やす事だってあるだろ。
その時に変な引数渡されるかもしれない。

502:デフォルトの名無しさん
08/11/20 23:38:59
>>489
483じゃないが。

X3010:2003の6.7.5.3の中ほど。
> 並びの中の唯一の項目がvoid型で名前の無い仮引数であるという特別な場合、関数が仮引数を持たないことを指定する。
(中略)
> 関数定義の一部である関数宣言子で識別子並びが空の場合、関数が仮引数を持たないことを指定する。
> 関数定義の一部で無い関数宣言子の識別子並びが空の場合、仮引数の個数および型の情報がないことを指定する。

でもこれって、C99なんだよね。C89とか規格書持っていないから俺は分からない。

503:デフォルトの名無しさん
08/11/20 23:39:40
>>495
オーバーロードはデフォルト引数が導入されてからずっと後にC++に取り込まれました
オーバーロードも理由の一つではありますが、そもそもはデフォルト引数です
そちらこそ知ったかはおやめ下さい

504:デフォルトの名無しさん
08/11/20 23:40:15
>>499
>そもそも間違って渡したから何だというのでしょう
間違って"渡さない"場合もあるだろ。
そしたらクラッシュするよ。

>型チェックのコストの方が高いという判断はありうることです
型チェックのコスト?
コンパイル時だからコストなんてかかんないよ

505:デフォルトの名無しさん
08/11/20 23:40:37
>>481
純粋な意味でのリンカがオブジェクトファイルを個別にチェックするのはちょっと考えられませんが。
昔の処理系では、生成したオブジェクトのほかスタートアップを陽にリンクするような方法も紹介されていました。(bccとか)

506:デフォルトの名無しさん
08/11/20 23:41:02
>>499
引数の数が間違っているとリターンがうまくいかないstdcallやpascalのことも忘れないでください。

507:デフォルトの名無しさん
08/11/20 23:42:17
>>505
なら前者を採用すればいい話だ。

508:デフォルトの名無しさん
08/11/20 23:43:10
>>504
引数をとらない関数に引数を間違って渡すとはどういう事でしょうか
意味がわかりません

引数を1個とる関数は当然に型チェックが必要ですよ
その1個の引数に間違った型でアクセスしたら大変なことになりますからね
でも引数をとらない関数は、そもそも引数自体にアクセスが出来ないのです
アクセスできない所に何が積まれようと知ったことではないのです

509:デフォルトの名無しさん
08/11/20 23:44:01
間違えました

>>504
引数をとらない関数に引数を間違って"渡さない"とはどういう事でしょうか
意味がわかりません

510:デフォルトの名無しさん
08/11/20 23:45:14
>>502
感謝です。
では、特に int main(void) という規約は必要ないことになるのですが、なぜわざわざ int main(void) という書き方を規約としたのでしょうか?
int main(void) を陽に指定する必要はないと思われるのですが。

511:デフォルトの名無しさん
08/11/20 23:45:56
>>505
int main(void)とint main(int argc, char **argv)でなくて恐縮だが、
VC++などでは、main/wmain/WinMain/wWinMainのどれが定義されているかによって、
リンクするスタートアップルーチンが変わるようになっている。

512:デフォルトの名無しさん
08/11/20 23:46:15
>>510
int main(void) と等価な書き方も許されるから
int main() も規格合致。

513:デフォルトの名無しさん
08/11/20 23:46:38
>>508
ばかだなぁ。
int hoge();
は、引数をとらないんじゃなくて、
どんな引数を渡してもいいって意味なんだよ。
わかる?

514:デフォルトの名無しさん
08/11/20 23:47:46
>>513
それも意味的には違うな。
引数に関して何も関知しないってことだな。
() は (...) とは意味が違う。

515:デフォルトの名無しさん
08/11/20 23:48:16
>>507
まあそれはそうですが、すでにその話は私のみならず他の方からも指摘されていたりするのです。>>422

516:デフォルトの名無しさん
08/11/20 23:49:33
>>515
>>422>>481 と同じ主張だ。

517:デフォルトの名無しさん
08/11/20 23:50:28
>>503
>オーバーロードはデフォルト引数が導入されてからずっと後にC++に取り込まれました
>オーバーロードも理由の一つではありますが、そもそもはデフォルト引数です
>そちらこそ知ったかはおやめ下さい
ダウト。
多重定義導入時にマングリングが導入された。

518:デフォルトの名無しさん
08/11/20 23:50:47
>>511
それは、リンカを制御する上位構造があるから、ではありますね。そのへんは理解しているつもりです。

519:デフォルトの名無しさん
08/11/20 23:51:18
なんでアホの好みの問題に振り回されてんの?

520:デフォルトの名無しさん
08/11/20 23:52:07
>>519
暇だからw

521:デフォルトの名無しさん
08/11/20 23:52:41
>>519
何か話題pls.

522:デフォルトの名無しさん
08/11/20 23:53:28
>>518
>リンカを制御する上位構造があるから


523:デフォルトの名無しさん
08/11/20 23:54:52
リンカオプションのことか

524:デフォルトの名無しさん
08/11/20 23:55:03
ん、やっと自らの過ちに気づいたかな?
今頃顔真っ赤かな?

525:デフォルトの名無しさん
08/11/20 23:55:39
そろそろISOにint main(void)の抹殺を嘆願する署名を集めてもよろしいでしょうか?

526:デフォルトの名無しさん
08/11/20 23:56:15
どうやらヤツは壮絶に勘違いしてたようだね
>>508のレスが証拠だね


527:デフォルトの名無しさん
08/11/20 23:57:43
>>525
お断りします
   ハハ
   (゚ω゚)
  /  \
((⊂ )  ノ\つ))
   (_⌒ヽ
   丶 ヘ |
εニ三 ノノ J


528:デフォルトの名無しさん
08/11/20 23:57:44
>>525
どうぞどうぞ

529:デフォルトの名無しさん
08/11/20 23:58:13
>>523
昔はコンパイラとリンカは別だったのですが。
その辺のニュアンスを含めて、「純粋なリンカ」と書きましたが、昔話ですみません。

530:デフォルトの名無しさん
08/11/20 23:58:55
今も別だろ・・・。

531:デフォルトの名無しさん
08/11/21 00:00:12
>>530
それは知りませんでした。多謝。

532:デフォルトの名無しさん
08/11/21 00:00:29
>>510
確かにint main()と書いても規格の意味するところは何も変わらない。

533:デフォルトの名無しさん
08/11/21 00:00:30
もうだめだ

534:デフォルトの名無しさん
08/11/21 00:01:40
実質的に一緒でしょう
今時本当にコンパイルしかしないコンパイラなんてごく稀ですよ
明示的にリンクを抑止するオプションでも指定しない限り

535:デフォルトの名無しさん
08/11/21 00:01:56
>>532
意味する所は変わらんが、
意味を正確に知るには別の箇所(6.7.5.3)も読まないといけないのが面倒だな。

536:デフォルトの名無しさん
08/11/21 00:02:28
>>534
それはコンパイラがリンカを呼んでるんだよ・・・。

537:デフォルトの名無しさん
08/11/21 00:02:37
やっとみなさんのおっしゃることがわかりました。
文法の誤解というか、勉強不足のところがありました。
お騒がせして申し訳ありませんでした。

538:デフォルトの名無しさん
08/11/21 00:04:07
>>534
コンパイラ単品ではあまりないかもしれないけど、
リンカ単品売りはあるよ。

539:デフォルトの名無しさん
08/11/21 00:06:07
>>518
VC++の場合、コンパイラを介さずともリンカにmainとかWinMainとかを持ったobjを食わすだけで判別する。

540:デフォルトの名無しさん
08/11/21 00:07:18
関数宣言で仮引数リストが空の場合と関数定義で空の場合で大違いなので
どっちの方を指してるのかちゃんと書き分けておくれ

541:デフォルトの名無しさん
08/11/21 00:08:13
>>540
お断りします
   ハハ
   (゚ω゚)
  /  \
((⊂ )  ノ\つ))
   (_⌒ヽ
   丶 ヘ |
εニ三 ノノ J

542:デフォルトの名無しさん
08/11/21 00:08:18
main は関数原型を書かないから
関数定義に決まってる

543:デフォルトの名無しさん
08/11/21 00:08:44
そういやC言語ってC++0xみたいなのって進んでるの?

544:デフォルトの名無しさん
08/11/21 00:10:59
C99 の先は一応議論されてはいるみたいだが、
あまり熱心ではなさそうだ。
C99 でもう C としては十分だろうし・・・。
これ以上追加していくと C++ になりそうだ。

545:デフォルトの名無しさん
08/11/21 00:12:43
C99でさえなかったことにされてるのにその先なんて…

546:デフォルトの名無しさん
08/11/21 00:13:22
>>542
書いたらダメなの?

547:デフォルトの名無しさん
08/11/21 00:15:05
>>542
そうとは限らんよ
URLリンク(binary.nahi.to)

まぁ相当変態なケースだけどなw

548:デフォルトの名無しさん
08/11/21 00:16:28
restrict とか [const] とかはやり過ぎだとは思うが
局所変数宣言位置自由とか inline とか
main での return 省略とかは地味に良いんだがなあ・・・。

549:デフォルトの名無しさん
08/11/21 00:18:17
C99なんかCじゃない
sizeofがコンパイル時に確定しないような変態言語がCを名乗るな

550:デフォルトの名無しさん
08/11/21 00:18:51
gcc拡張が標準化されればいいや

551:デフォルトの名無しさん
08/11/21 00:19:27
>>549
kwsk

552:デフォルトの名無しさん
08/11/21 00:21:39
void f(int n)
{

}

553:デフォルトの名無しさん
08/11/21 00:22:06
int a[n]; の時の sizeof a が実行時に決まるってだけだ

554:デフォルトの名無しさん
08/11/21 00:22:13
おっと途中送信
void f(int n)
{
  char c[n];

}

555:デフォルトの名無しさん
08/11/21 00:22:51
この2chブラウザあかんわ

556:デフォルトの名無しさん
08/11/21 00:23:22
>>543
こういう感じらしい。
URLリンク(www.hi-matic.org)

557:デフォルトの名無しさん
08/11/21 00:24:12
>>547
おもしれーなw

558:デフォルトの名無しさん
08/11/21 00:25:12
>>553
thx!
むしろint a[n]; ができる方がすげー

559:デフォルトの名無しさん
08/11/21 00:26:42
alloca みたいなもんだな。
スタック上に確保されるだろうから
大きな値を使われるとオーバーフローするかもな。

560:デフォルトの名無しさん
08/11/21 10:58:31
馬鹿ばっか

561:デフォルトの名無しさん
08/11/21 11:01:31
longjmpで抜けた場合には解放される保証がないということから、処理系によってはヒープ上かも

562:デフォルトの名無しさん
08/11/21 17:56:36
mainを呼ぶWinMainを書いたことがある俺

563:デフォルトの名無しさん
08/11/21 18:59:13
main = 0x909090C9;

564:デフォルトの名無しさん
08/11/21 23:42:04
>>561
> longjmpで抜けた場合には解放される保証がない
ここを詳しく


565:デフォルトの名無しさん
08/11/21 23:49:03
longjmpで抜ければ、普通スタックは巻き戻される。
つまりスタックにallocateしているなら、解放される。

mallocしたメモリと同じようにヒープに確保して、
暗黙のうちに関数のエピローグでfreeしているとすると
longjmpで抜けてしまうと関数のエピローグを通らないから
freeされない。つまり、解放される保証がない。

566:デフォルトの名無しさん
08/11/22 00:18:34
保証が無いってのが微妙な表現だな。
スタック使っても、ヒープ使っても、
サイズによってどっち使うか決めても規格合致ってことか。

567:デフォルトの名無しさん
08/11/22 00:33:57
>>564
longjmpのところに↓のようなことが書かれてる

EXAMPLE The longjmp function that returns control back to the point of the setjmp invocation
might cause memory associated with a variable length array object to be squandered.
#include <setjmp.h>
jmp_buf buf;
void g(int n);
void h(int n);
int n = 6;
void f(void)
{
int x[n]; // OK, f is not terminated.
setjmp(buf);
g(n);
}
void g(int n)
{
int a[n]; // a may remain allocated.
h(n);
}
void h(int n)
{
int b[n]; // b may remain allocated.
longjmp(buf,2); // might cause memory loss.
}

568:デフォルトの名無しさん
08/11/22 00:38:09
なるほど。may に might か。
開放される実装になってても規格違反ってわけじゃないのね。

569:デフォルトの名無しさん
08/11/22 06:35:20
関係ないけど、そのsetjmpの使い方、未定義ですな

570:デフォルトの名無しさん
08/11/22 11:40:43
知らんがな(´・ω・`)

571:デフォルトの名無しさん
08/11/23 09:05:10
setjmpは条件式の中からしか呼べないんだっけ?

572:デフォルトの名無しさん
08/11/23 13:03:50
なんだ? そのわけわかめな制限は。

573:デフォルトの名無しさん
08/11/23 13:35:20
setjmp の使い方を考えれば至極妥当だと思うが・・・。
無限ループになるぜ。

574:デフォルトの名無しさん
08/11/23 13:38:23
無限ループになるかどうかも未定義か

575:デフォルトの名無しさん
08/11/23 13:40:44
An invocation of the setjmp macro shall appear only in one of the following contexts:
- the entire controlling expression of a selection or iteration statement;
- one operand of a relational or equality operator with the other operand an integer
constant expression, with the resulting expression being the entire controlling
expression of a selection or iteration statement;
- the operand of a unary ! operator with the resulting expression being the entire
controlling expression of a selection or iteration statement; or
- the entire expression of an expression statement (possibly cast to void).
If the invocation appears in any other context, the behavior is undefined.

・・・だそうだ

576:デフォルトの名無しさん
08/11/23 13:43:11
環境限界 setjmp マクロの呼出しは,次に示すいずれかの文脈にしか現れてはならない。

・選択文又は繰返し文の制御式全体
・他方のオペランドが整数定数式である関係演算子又は等価演算子の一方のオペランド。
 この場合,関係演算子又は等価演算子による式は,選択文又は繰返し文の制御式全体でなければならない。
・単項 ! 演算子のオペランド。この場合,単項 ! 演算子による式は,選択文又は繰返し文の制御式全体でなければならない。
・式文の式全体(void にキャストされていてもよい。)。
 setjmp マクロの呼出しがこれ以外の文脈に現れた場合,その動作は,未定義とする。

要するに、
・「if(A)」「switch(A)」「while(A)」「for(X;A;Y)」のどれかのAの場所に、
「setjmp(buf)」「setjmp(buf) op Z」「Z op setjmp(buf)」「!setjmp(buf)」(opは> < >= <= == !=のどれか)
のいずれかの形で出てくるか
・単に「setjmp(buf);」「(void)setjmp(buf);」の形で出てくるか

どっちかでないと鼻から悪魔

577:デフォルトの名無しさん
08/11/23 13:45:52
なら別にそのまま使ってもいいのか。

578:デフォルトの名無しさん
08/11/23 14:04:21
制御文の中で直接真偽判定する以外にその値を使ってはいけないってことかな

579:デフォルトの名無しさん
08/11/23 14:10:20
longjumpから帰ってきたかどうかを示す値が揮発性だってこと?

580:デフォルトの名無しさん
08/11/23 22:36:28
sequence point間に単独で置いとけってことだろう。

581:372
08/11/24 09:28:32
関連の規約をチェックしました。>>537 は実は別人ですが、同じ気持ちです。感謝です。
>>502, >>535 ポインタを紹介していただきありがとうございました。非常に勉強になりました。
なお、>>508 は私ではありません。

582:デフォルトの名無しさん
08/11/24 15:09:46
久しぶりに覗いてみたら、かつてのfj.lang.cなみのマジキチぶりにワロタ

583:デフォルトの名無しさん
08/11/24 15:36:09
>>582
それは賛辞に取られかれない危険な発言かと。

584:デフォルトの名無しさん
08/11/24 23:39:27
fj.lang.cってどこのサイトですか?

585:デフォルトの名無しさん
08/11/25 00:05:57
>>584
Wikipedia項目リンク(%E3%83%8B%E3%83%A5%E3%83%BC%E3%82%B9%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97)

586:デフォルトの名無しさん
08/11/25 00:16:53
>>585
トン。
理解力ないんでよくわかんなかったw
スレタイよくみたら初心者お断りなので帰ります。。。λ

587:デフォルトの名無しさん
08/11/27 13:57:38
>>584
マジレスするとネットニュース。
Webからアクセスできるゲートウェイも存在するが、
「どこのサイト?」とか言っちゃうあたり時代はかわったんだなぁと思った。

588:デフォルトの名無しさん
08/11/27 14:11:53
俺は>>584ネタかと思ったよ

589:デフォルトの名無しさん
08/12/10 00:27:10
俺はパソコン通信からやってるけど
本格的にインターネットを使いだしたのが
遅かったので知らない。

590:デフォルトの名無しさん
08/12/10 09:27:58


■■■■■■

591:デフォルトの名無しさん
08/12/10 09:35:00
■■■■■■■■■■■

592:デフォルトの名無しさん
08/12/10 11:55:31
>>589
まだナツメネットとかアスキーNETとかw

593:デフォルトの名無しさん
08/12/10 13:41:40
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
2ちゃんねるという馬鹿な掲示板を削除してくでさい
ドコモ規制するとか頭おかしいんじゃねーの?

のんたん
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■

594:デフォルトの名無しさん
08/12/10 13:47:50
      __     ,.-、
.      l _ヽ     .l ri.ヽ
     l l ヽヽ.  // l. !
     l l,.- '  ̄  ̄ ! .,
.      l  rn  ,.、 n ,.イ,.-   _
    二l- `'' ヽニノ- _,フー‐  r ,.-- '
.    -‐`ーr'´ 〉 ´  、 `ヽ ,! l
         ヽ-r'     ヽ' ノ /
         ヽ、      .l' ´
          /´  /   !
         ⊂._,.!   _/
              ̄

595:デフォルトの名無しさん
08/12/10 17:42:48
ご冥福をお祈りします

596:デフォルトの名無しさん
08/12/22 01:21:46
あげ

597:デフォルトの名無しさん
08/12/24 21:10:13
a.cでint iというグローバル変数を定義して
b.cでint iという同名のグローバル変数を定義しても
多重定義にならないのは何故ですか?

598:デフォルトの名無しさん
08/12/24 21:19:07
>>597
>>133-

599:デフォルトの名無しさん
08/12/24 21:21:53
>>598
ありがとうございます。

600:デフォルトの名無しさん
08/12/26 19:39:16
URLリンク(d.hatena.ne.jp)
これってどうなの?

601:デフォルトの名無しさん
08/12/26 22:47:14
>>600
似たような話で、規格にはプログラムのサイズについて規定は無いが、実際には有限だ。

関数定義が CPU インストラクションの列で実装されていれば、対象環境の
プログラム配置領域サイズによって制限を受ける。

同じように、自動記憶域がスタックで実装されていれば、対象環境でのスタックの
サイズに応じてプログラムが制限を受ける。

そういうことだと思う。つまりは、言語の規格は上記のような制限の無い仮想マシンに
ついての動作を規定するもので、実装方法や実際の動作環境によって生じる制限には
関知しない、と。

602:デフォルトの名無しさん
08/12/27 00:01:54
現実のコンピュータでCの規格に完全準拠することは理論上不可能
ってことでいいのか。ありがとう、すっきりした。

603:デフォルトの名無しさん
08/12/27 00:06:30
理論上はそうなってしまうので、規格には最低限満たして欲しい基準が補足で書かれてる

604:デフォルトの名無しさん
08/12/27 00:10:00
>>603
どこ?

605:デフォルトの名無しさん
08/12/27 00:10:28
処理系限界が下限に限らず存在することが規定されている

606:デフォルトの名無しさん
08/12/27 00:15:38
>>602
ブログの人はそういってるけど 601 は違うといってるんだが。

607:デフォルトの名無しさん
08/12/27 00:19:16
>>606
じゃあ理論上可能なの?

608:デフォルトの名無しさん
08/12/27 00:19:38
Cでは基本的に「ハードウェアのやることはなんでもあり」であって、
規格はハードウェアに発する命令の体系を既定しているに過ぎない。
ハードウェアの能力が足りなくて要求を実現できないのと、
実装が規格に準拠しているかどうかはまったく別の問題。

609:デフォルトの名無しさん
08/12/27 00:24:06
>>607
601 を読んだうえで、不可能だと思う理由を述べてください。

610:デフォルトの名無しさん
08/12/27 00:24:12
>>604
AnnexB

611:デフォルトの名無しさん
08/12/27 00:41:21
>>608
メモリ無限の仮想マシンの上で動くバイナリを出力するコンパイラなら
理論上は作れる。実行はできないが。
ってこと? そういうことなら納得。

>>610
Annex BはLibrary summaryになってる。
手元にC99のCommittee Draftしかないんだけど。

612:デフォルトの名無しさん
08/12/27 02:34:54
>>611
いや、言語として規定はないから作れる。実行も出来る。
ただ実行した時の結果・挙動についてまでは保証しませんよってこと。

C言語としてはこの場合、「無限再帰呼び出しを行うマシンコードが生成される」
ところまでしか保証しない(コンパイラによっては警告出すかもしらんが)。
それを実行した結果、何が起こるかかまでは規定できないし、しない。

int *p = 0; *p = 100;
このコードがコンパイル出来ますか?実行出来ますか?
って問題と同じだろう。コンパイルも実行も可能だが、結果は環境に依存する。

613:デフォルトの名無しさん
08/12/27 14:44:56
末尾再帰だからループに直すのだ!

614:デフォルトの名無しさん
08/12/27 16:52:07
>>612
> int *p = 0; *p = 100;
これは未定義だってはっきりしてるじゃん。別の話。

615:デフォルトの名無しさん
08/12/27 19:26:24
int *p = 0; *p = (int*)100;じゃないとコンパイル通らなくないか?

616:デフォルトの名無しさん
08/12/27 19:31:13
>>615 試してから書けよ。

617:デフォルトの名無しさん
08/12/27 19:34:15
ごめんポインタ2つ宣言してるように見えてた

618:デフォルトの名無しさん
08/12/27 19:41:07
>>611
その理解であってると思う。極端な話、現実のCPUやOSは物理的に故障する可能性が
あるのに、その上でC言語の仕様に完全に準拠するなんて不可能だ。

>>612
コンパイラの仕事は、入力したソースコードの意味と同じ意味を持つ実行ファイルを
出力すること。実行ファイルの意味はCPUやOSの仕様が規定している。CPUやOSが自身の
仕様通りに動くときは「実行した時の結果・挙動」を保証しないと、「C言語の仕様に
準拠したコンパイラ」とは言えない。

ってか、C言語の仕様は実現方法を規定しないから、「無限再帰呼び出しを行うマシン
コードが生成される」ことも保証されないぞ。

619:デフォルトの名無しさん
09/01/20 21:40:47
setbuf, setvbuf 関数で自らバッファをmallocして設定したとき、fcloseしたらそのバッファもfreeされるのでしょうか?
もしくはそのバッファは(gccでは)どういう運命をたどるのでしょうか。

620:デフォルトの名無しさん
09/01/20 21:57:51
RTFM


621:デフォルトの名無しさん
09/01/22 00:05:37
>>619
glibcだとユーザーが定義したバッファは開放されないみたい。

622:デフォルトの名無しさん
09/01/22 01:00:00
>>621
ありがとうございます。
linux manをみても、NULLの場合は開放とあるのですがユーザ設定のときは言及もなく未定義とも書いてなかったので。


623:デフォルトの名無しさん
09/01/22 04:44:41
ユーザがセットしたバッファがfreeして良い(すなわち、mallocされている)のか、
静的に確保されたメモリ領域など、freeしてはならないのかは、
fcloseには分らないから、fcloseの実装でユーザがセットしたバッファを
freeすることはあり得ない。


624:デフォルトの名無しさん
09/01/22 04:55:22
>>619
フツーに考えたら、freeされないと思う。
根拠はオレ。

仕様的には実装におまかせのはず。


625:デフォルトの名無しさん
09/01/22 22:34:44
複数行マクロを書くときの体裁なんですが、
伝統的なdo{}while(0)ではなくvoidキャストを使うというのを見かけました
たとえばこんなんです

#define macro() { /* 処理 */; }(void)0

確かにこれでうまくいきそうに見えるのですが、本当の本当に大丈夫でしょうか


626:デフォルトの名無しさん
09/01/22 22:36:44
>>625
if(hoge)macro();else foo;
でアウツだろ。

627:デフォルトの名無しさん
09/01/22 22:42:23
なるほど

#define macro() if(1){ /* 処理 */; }(void)0

なら大丈夫ですか?

628:デフォルトの名無しさん
09/01/22 22:43:55
違うか

#define macro() if(1){ /* 処理 */; }else (void)0



629:デフォルトの名無しさん
09/01/22 22:47:55
問題は無いと思う。
まあ、そこまでするなら do { } while(0) の方がシンプルでいいと思うが。
これの問題は条件式が定数式の場合に警告吐くコンパイラがあるという点だが、
それが解決されてるわけでもないしね。

630:デフォルトの名無しさん
09/01/22 22:54:28
>>628 にはまだこの問題があるようだ。
macro(), foo(); /* foo() は実行されない */

631:デフォルトの名無しさん
09/01/23 09:01:12
それはdo〜whileでも駄目なのでは?

632:デフォルトの名無しさん
09/01/23 17:38:36
do〜whileはコンパイルエラーになってくれる
628はコンパイル通って実行しないからタチが悪い

633:デフォルトの名無しさん
09/01/24 08:47:00
#define macro() { /* 処理 */; }
だけではだめなんですか?

634:デフォルトの名無しさん
09/01/24 08:58:37
if (hoge)
 macro(); /* ← 使う側はどういう定義になっているか知らないのでセミコロンをつけて書いちゃった */
else
 foo();

で文法エラーになる。
常に if に { } を付けるスタイルなら問題は無いが。

635:デフォルトの名無しさん
09/01/24 09:41:12
なるほど。

636:デフォルトの名無しさん
09/01/24 09:42:54
ともあれこのスレは、Cのイディオムについて語り合うスレではないな。

637:デフォルトの名無しさん
09/01/24 12:54:33
>>636
誰がそんなこと決めた

638:デフォルトの名無しさん
09/01/24 18:00:48
文法エラーではじかれるならまだOKですね。
変に動いて誤作動するよりは。

基本ifには{}をつけるので
#define macro() { /* 処理 */; }
でも問題ないですが、これだとMISRA-Cに怒られる・・・

639:デフォルトの名無しさん
09/01/24 18:43:46
inline macro() { /* 処理 */; }
が一番だな

640:デフォルトの名無しさん
09/01/24 18:50:15
inlineの基準はコンパイラによって違うそうですが、たとえばgccではインラインされるかどうかのある程度基準(仕様)があるんですか?

641:デフォルトの名無しさん
09/01/24 18:55:23
inlineじゃなくて、static宣言された関数では?

642:デフォルトの名無しさん
09/01/24 18:55:54
>>641
C99でinlineが入ったんだよ。

643:デフォルトの名無しさん
09/01/24 19:18:31
inlineとstaticは同じ基準でインライン展開されるんですか。

644:デフォルトの名無しさん
09/01/24 19:19:07
よーわからんけど、extern inline が使えるってこと?

645:デフォルトの名無しさん
09/01/24 20:40:50
>>643
コンパイラ次第。
最適化レベルによって基準に差が出たり出なかったりする、なんてこともある。

646:デフォルトの名無しさん
09/01/24 20:41:26
>>644
inline 関数は常に内部リンケージ。

647:デフォルトの名無しさん
09/01/25 02:27:15
最適化をしない設定ではinlineをしていしても無効になるコンパイラもあるしね。

648:デフォルトの名無しさん
09/01/25 05:53:01
極端な話、今時inlineなんてregster程度の意味しかないと言ってもいい。

649:デフォルトの名無しさん
09/01/25 10:58:41
register
 ・ C ではアドレスを取るとエラーになる(C++ では問題ない)
 ・ レジスタにするかどうかは 100% 無視される
inline
 ・ 最適化なしでは static 関数も inline 関数もインライン化されない
 ・ 最適化低では inline 関数はインライン化されるが static 関数はインライン化されない
 ・ 最適化高では static 関数も inline 関数もインライン化される

VC++ ではこんな感じだったと思う。
分岐する最適化レベルがいくらだったかは忘れた。

650:デフォルトの名無しさん
09/01/25 16:20:26
>>649
ありがとうござます。
inlineはコンパイラによってインライン展開するかどうかは任意だと聞いてたんですけど、最適化を協力にすると任意じゃなくて必ず展開されるんですか
それと、static関数は必ずインライン展開されるんですか。困った話ですね。

ということは、インラインとしては展開できない関数はないですね(つまり必ずマクロ関数みたくなる)。
inlineは最適化から出てきた機能ですが(関数専用の)テンプレートに近くなっているということでしょうか。

651:デフォルトの名無しさん
09/01/25 16:23:03
>>650
いやいや、必ず展開されるという意味で書いたわけじゃない。
「インライン化されない」と書いた部分は「必ずインライン化されない」が、
「インライン化される」と書いた部分は「インライン化される可能性がある」の意味で書いた。

652:デフォルトの名無しさん
09/01/25 16:44:33
今のハードなら展開されようが、されまいがどうでもいいんじゃないの。
関数呼び出しコストなんて測定できないような時間(ナノ秒単位)で、普通は参照渡し。
組み込みとかセットボックスみたいだとハード資源が限られてるからループ内部とかでやれば多少効果はあるかもしれない。

653:デフォルトの名無しさん
09/01/25 16:53:46
画像処理とか激しいループは未だにあるもんだ。

654:デフォルトの名無しさん
09/01/25 17:36:24
インライン展開することによる最適化も期待できるから
>>652 は世間知らずだな としか思えない。

655:デフォルトの名無しさん
09/01/25 17:44:03
static以外の関数でも最適化を上げればインライン展開されると思うよ。
外部リンケージ用に、通常関数版も用意されるはずだけど。

656:デフォルトの名無しさん
09/01/25 17:49:42
まあそこらへんは規格に反しない限りはコンパイラが自由にやっていいことだからなぁ

657:デフォルトの名無しさん
09/01/25 18:53:36
ファイルのリンケージを考えれば、どっちでもいいということですね。
オブジェクトファイルのサイズが増えても今のハード(携帯なども含む)なら微々たる物でしょうし。
気にしているのは、DLLみたく他人がつかうとき、それが関数のつもりがマクロみたく展開されてると不都合が生じるってことです。
関数ポインタのときとか。

658:デフォルトの名無しさん
09/01/25 22:09:36
>>657
> 気にしているのは、DLLみたく他人がつかうとき、それが関数のつもりが
> マクロみたく展開されてると不都合が生じるってことです。
> 関数ポインタのときとか。

意味わからん、inline の意味わかってるのか?

659:デフォルトの名無しさん
09/01/26 00:18:35
実行時の関数呼び出しとコンパイル時のインライン展開の違いはわかってる?

660:デフォルトの名無しさん
09/01/26 00:20:50
inline 関数の中に malloc があったとき
どっち側でメモリが確保されるのかは気にはなる。

661:デフォルトの名無しさん
09/01/26 00:25:31
何側と何側の話をしているんだ

662:デフォルトの名無しさん
09/01/26 00:29:45
DLL側とDLLを使用している側

663:デフォルトの名無しさん
09/01/26 00:31:33
説明する気もうせる

664:デフォルトの名無しさん
09/01/26 00:33:09
スレチだしな

665:デフォルトの名無しさん
09/01/26 00:38:12
いいぞもっとやれ

666:デフォルトの名無しさん
09/01/26 01:01:17
>>658-659

inline void func();

これを(*func)と関数ポインタで使うときどうなるんでしょうか?
例えばqsortに渡したりするときも、qsortみたいな関数ポインタを受け付けるAPIは実行時評価が目的の設計なので、
インライン展開されると不都合な気がするんですけど。

static関数もファイルスコープにおいて展開されるのは初耳だったんですけど、同じように実行時に不都合がありませんか?

667:デフォルトの名無しさん
09/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:デフォルトの名無しさん
09/01/26 01:21:53
うん。

669:デフォルトの名無しさん
09/01/26 01:29:38
>>666
上で誰かが書いていたと思うけど、必要なら普通の関数のコードも併せて作るだけ。

670:デフォルトの名無しさん
09/01/26 05:22:44
>>669
私だよん。

>>666
たまにはアセンブリ出力を眺めてみるもんだよ。
個々の行の意味が判らなくても、全体のボリュームとシンボルの位置でいろんなことが見えてくる。

>>667
その通り。実際、1,0,-1しか返さない処理系もあった筈だし、
最初に不一致だったバイトの差分を返す処理系もあった筈。

671:デフォルトの名無しさん
09/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:デフォルトの名無しさん
09/02/14 07:29:40
なんか、とても杞憂な気がするるが、神経質にするならこうか?

c= isalpha((unsigned char) c) ? toupper((unsigned char)c) : c;

673:デフォルトの名無しさん
09/02/14 07:42:03
気になってるのは、大文字アルファベットの表現がsinged charで負値になる環境とかだよね。

全く規格確認してないが、intの戻り値retについて、
CHAR_MINが負値でretがCHAR_MAXを超える場合、
自力でunsigned charをcharに変換するコードを書けば
とりあえず解決するんじゃね?

1バイト文字の英数がASCIIで無い処理系ってあんま想定したこと無いから分からないけども、
「ASCIIじゃなきゃダメ」って記述は規格には無かった気がするなぁ。
詳しい人フォローよろしく。

674:デフォルトの名無しさん
09/02/14 07:44:12
fgetc() なんかも同じだよね。とりあえず EOF をチェックして、それが済んだら char として
扱いたいんだけど、変換できるの?っていう。

675:デフォルトの名無しさん
09/02/14 09:13:41
>>671
そもそも規格上は unsigned char を signed long するだけでだめなケースがあるから

> 未定義動作も実装依存も回避した移植性のある方法はあるのでしょうか?

の答えは「ない」だよ。

>>673
> 「ASCIIじゃなきゃダメ」って記述は規格には無かった気がするなぁ。

汎用機用の C言語処理系で文字コードが EBCDIC のものがある。

676:デフォルトの名無しさん
09/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:デフォルトの名無しさん
09/02/14 10:11:11
>676
明示的に UCHAR_MAX を与えるわけじゃなくて、unsigned char に変換すると UCHAR_MAX になる値が
char としてあった場合に、unsigned char にキャストしてから toupper に与えた場合とか。

> toupper()やfgetc()の結果をcharと比較したい場合、
比較ならいいけど、char に代入したくなったらどうするの?
例えば、文字列中の小文字を全て大文字に変換する関数 strupper(char*) を定義しようとかいう場合。
やっぱ >672 のように書けってことだろうか。

678:デフォルトの名無しさん
09/02/14 10:13:56
>>676
> toupper()やfgetc()の結果をcharと比較したい場合、

単純比較なんて誰も悩んでないと思うが。
配列に入れて、printf() で出力したい時とか考えつかないわけ?

679:デフォルトの名無しさん
09/02/14 11:51:23
signed char が -127〜127 で文字コードが 0〜255 の環境なら、
処理系は char を unsigned char 固定で扱うようになっているんじゃないのか?
じゃないと char が文字コードを収める事ができるという
最低条件をクリアできないじゃん。

680:デフォルトの名無しさん
09/02/14 11:56:18
>>677
>>unsigned char にキャストしてから toupper に与えた場合とか。

だから、なんでキャストするの?

入力が signed char なら signed char → int に変換されても
UCHAR_MAX はありえない。

入力が unsigned char なら UCHAR_MAX はありうるけど、それは
変換前も変換後も UCHAR_MAX のままでしょ


681:デフォルトの名無しさん
09/02/14 13:17:25
>>680
ふふ、

682:デフォルトの名無しさん
09/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:デフォルトの名無しさん
09/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
09/02/14 22:52:12
>>683
その文章は知ってるよ。
でもそれは toupper の引数は unsigned char でキャストしろ、って意味.じゃない
signed char を指定した場合で -2 〜 -128 の場合は undefined だよ、って言ってるだけ
(EOFが-1として)

685:デフォルトの名無しさん
09/02/15 00:14:28
実際死ぬケースもあったな。マイナス与えると。
日本語扱うとよくある。

686:デフォルトの名無しさん
09/02/15 00:16:35
> 未定義動作も実装依存も回避した移植性のある方法はあるのでしょうか?
最初っから全部unsigned charにしとけでイナフ

687:デフォルトの名無しさん
09/02/15 00:23:38
>>679 についてはどうなんだ?

688:デフォルトの名無しさん
09/02/15 01:03:33
>>684
未定義動作を回避するのに、 unsigned char にキャストするほかにどうすんの?

689:デフォルトの名無しさん
09/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:デフォルトの名無しさん
09/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 以外なら負値も認めているように読めるけど、
後は実装依存の闇の中、かな。


次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

5405日前に更新/178 KB
担当:undef