[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 2chのread.cgiへ]
Update time : 05/09 19:03 / Filesize : 146 KB / Number-of Response : 644
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

【ISO/ANSI/JIS】 C言語なら俺に聞け! Part 132



1 名前:デフォルトの名無しさん mailto:sage [2007/09/20(木) 13:10:57 ]
このスレは標準Cのみの限定スレです。
まず問題を冷静に吟味してCの話か否かをはっきりさせてから質問しましょう。
質問する前には最低限検索を。
エラー(警告含む)が起きたのならばエラーメッセージを書きましょう。

C FAQ 日本語訳
www.kouno.jp/home/c_faq/
Cプログラマ必読 ・プログラミング言語C(通称 K&R)
www.amazon.co.jp/exec/obidos/ASIN/4320026926/250-7563469-9920244

他の過去ログはここに
nssearch.hp.infoseek.co.jp/clang/
前スレ
【ISO/ANSI/JIS】 C言語なら俺に聞け! Part 131
pc11.2ch.net/test/read.cgi/tech/1170338926/


GUIなどの標準Cではできない事の質問、ソース丸投げ、宿題、書籍 は
専門の別スレッド↓があるのでそこへさようなら。

【初心者歓迎】C/C++室 Ver.42【環境依存OK】
pc11.2ch.net/test/read.cgi/tech/1188748806/
C/C++の宿題を片付けます 95代目
pc11.2ch.net/test/read.cgi/tech/1187944110/


【このスレ住人としての心得】
ビットシフトはなんの役に立つのでしょうか でググれ

367 名前:デフォルトの名無しさん mailto:sage [2007/10/15(月) 23:47:42 ]
>>366
int data3[]=0;

368 名前:デフォルトの名無しさん [2007/10/16(火) 00:13:38 ]
>>367
どうすればいいですか?

369 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 00:19:25 ]
>>363
未初期化の変数のロケーションを、必ず、読む、というコードが生成される、はず
規格では未初期化の自動変数を読んだ場合のふるまいはどうだっけ?

実際、どういう場合にまずいかというと
処理系(ここで言う処理系にはOS以下メモリやプロセッサまで含む)によっては
プロセスが、まだ書いたことのないロケーションを読もうとすると、メモリの
ゴミあさり(他のプロセスがパスワードとかを残してたりするの探す)と判断されて
例外で落とされるかもしれない、とか

370 名前:361=363 mailto:sage [2007/10/16(火) 00:22:31 ]
あぁぁぁすいません
変数は初期済みという前提でおながいします

371 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 00:23:05 ]
>>368
int data3[N]={0};
他にもおかしいところがあるかもしれないけど見てない

372 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 00:26:17 ]
>>363
volatileオブジェクトは例えばプロセッサの内蔵タイマのようなリアルタイムに値の変化するものを指しているかもしれない。

373 名前:デフォルトの名無しさん [2007/10/16(火) 00:27:16 ]
ありがとうございます。
そこを直してもまだ1つエラーがありました。
data3[i + j] = data[i];
ここらしいです

374 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 00:27:36 ]
>>363
メモリマップド I/O だな。読んだだけでチップの信号が変わるとか。

375 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 00:28:33 ]
>>373
エラーメッセージ嫁。
読んで分からなかったらエラーメッセージ添えて聞け。
ここはエスパーごっこするスレじゃない。



376 名前:363 mailto:sage [2007/10/16(火) 00:29:41 ]
>>372
>>374
なるほど。ハードウェア絡みですね

確かに読むだけでデバイスの状態が変化する可能性がありますね

ありがとうございました!

377 名前:デフォルトの名無しさん [2007/10/16(火) 00:31:43 ]
>>375
すみません。
エラー E2451 babble.cpp 10: 未定義のシンボル data(関数 main() )
だそうです。

378 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 00:34:28 ]
>>377
dataは1〜3だろ、無印は無い
たぶんdata3[i + j] = data1[i];

379 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 00:38:27 ]
>>377
なんでそこまで言われて気づかないんだ?

380 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 00:40:35 ]
BCC はこれがコンパイルエラーじゃなくてリンクエラーになるのか。恐ろしいな。
っていうか悪いことは言わないから VC++ 2005 EE か Cygwin GCC にしとけ。

381 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 00:42:08 ]
いくらBCCでもコンパイル通らないだろ

382 名前:デフォルトの名無しさん [2007/10/16(火) 00:43:00 ]
完全な見落としですね…
すみません。ありがとうございました

383 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 00:58:14 ]
>>371

Cの配列は自動で領域拡張してくれないからdata3のメモリ領域は必ず確保することが必要だと。
data3[] = {0};
だとdata3の配列の長さは1です。今のままだと条件によってはバッファーオーバーランします。


384 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 01:10:34 ]
たまたま質問が標準C以内のものだったら回答してるって感じだな
>>366なんか標準Cと何の関係もない、ただのデバッグ依頼だろ
ちゃんと切り分けろよ

385 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 01:10:34 ]
>>383
Nがわざわざ定義してあるだろ



386 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 01:20:08 ]
>>371
現状の結果は data3[] = {3,*,*,*,*};
となる。*部は未定義かつ異常アクセス。
このデータの場合読み込みしかしていないが
二つのif条件が共に満たされている場合始めの*に書き込み
Windouwsなら共有違反のエラーダイアログが出て強制終了されると思います。



387 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 01:24:34 ]
突っ込むの面倒だし放置でいいかな?

388 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 01:27:28 ]
なんでいきなりBCC

389 名前:384=386 mailto:sage [2007/10/16(火) 21:29:10 ]
一つ見落としてました御免なさい…

390 名前:デフォルトの名無しさん mailto:sage [2007/10/23(火) 23:39:29 ]
ぬるぽ

391 名前:デフォルトの名無しさん mailto:sage [2007/10/23(火) 23:56:21 ]
ガッ

392 名前:デフォルトの名無しさん mailto:sage [2007/10/25(木) 02:01:37 ]
int a = -1;
unsigned int b = a;
こうするとbは標準Cならどんな環境でもUINT_MAXになるんですが

unsigned int b = (unsigned int)a;
こうした場合って、このキャストは
(1)aのビットパターンを無理やり unsigned int として解釈するのか (C++のreinterpret_cast)
→負数の表現が2の補数なら UINT_MAX
 1の補数なら UINT_MAX-1
 絶対値と符号フラグなら…いくつだ?

(2)aをunsigned int に変換するのか (C++のstatic_cast)
→環境によらず UINT_MAX

どっちでしょうか?
あいにく手元には負数の表現方法が2の補数の環境しかないので、確かめられません

393 名前:デフォルトの名無しさん mailto:sage [2007/10/25(木) 02:06:39 ]
って、>>189に書いてある説明文に思いっきり
(unsigned int)-1 って書いてあるな…

394 名前:デフォルトの名無しさん mailto:sage [2007/10/25(木) 02:16:57 ]
>>392
C の話は解決したとして、 C++ の reinterpret_cast の理解が間違ってる。
reinterpret_cast で int → unsigned int の変換はできない。
reinterpret_cast による変換結果はすべて実装依存。ビットパターン云々とは言えない。

395 名前:デフォルトの名無しさん [2007/10/26(金) 12:00:55 ]
>>364 volatile修飾子は、組み込み用プログラムでは多用するな。

    最適化では、値を読むことしかしてない変数は無駄なコードとして
   削除されてしまう。
   
    しかし、メモリマップドI/Oでは、I/Oのレジスタ類は変数として
   定義され、その内容の変化のみをチェックする処理は多い。 その様な
   変数には、volatile修飾子をつけないと最適化で消されてしまって
   処理が実行されない。 Cソース上では存在するが、機械語コードでは
   存在しなくなっている。 これを防止するのが主な使い方だな。




396 名前:デフォルトの名無しさん mailto:sage [2007/10/26(金) 14:43:41 ]
>>395
それで思い出したがCPU自体にアトミックな操作ができない物があり、
そういうCPUではvolatileを完全に実現出来ないと聞いた。

具体的には16ビットCPUで32ビット変数を扱うと完全なvolatileには
ならない。16 + 16に分けて2回読み書きするためで、その間に割り込み
が入って内容を変更されてもCPUはそれに気づけない。

397 名前:デフォルトの名無しさん mailto:sage [2007/10/26(金) 16:52:48 ]
>>396
>volatileを完全に実現出来ない
それは適当な表現じゃないなぁ。
単にvolatileではアトミックかどうかを意識できないだけの話だと思うんだ。
volatileがそれを保証する修飾子じゃないんだから実現できないってのとは違うでしょ。

398 名前:デフォルトの名無しさん mailto:sage [2007/10/26(金) 17:12:01 ]
>>397
§6.7.3.6
An object that has volatile-qualified type may be modified in ways unknown to the
implementation or have other unknown side effects. Therefore any expression referring
to such an object shall be evaluated strictly according to the rules of the abstract machine,
as described in 5.1.2.3. Furthermore, at every sequence point the value last stored in the
object shall agree with that prescribed by the abstract machine, except as modified by
theunknown factors mentioned previously.114) What constitutes an access to an object that
has volatile-qualified type is implementation-defined.

確かに実装依存と書いてあるね。しかしアトミックである事を保証できないのならvolatile修飾子の意味は
無い事になってしまう。規格には保証されてなくても実際volatileをそのような目的に使うなら、CPU固有の
振る舞いを知っておく事は非常に重要なはずだ。

399 名前:デフォルトの名無しさん mailto:sage [2007/10/26(金) 17:30:16 ]
主旨には同意するが

> アトミックである事を保証できないのならvolatile修飾子の意味は
> 無い事になってしまう。

これは言い過ぎ。例えば
volatile x;
x = 2;
x = 3;
の x = 2; が実行されることが保証されること等、
アトミシティ以外にも存在する意味はある。

400 名前:デフォルトの名無しさん mailto:sage [2007/10/26(金) 17:57:20 ]
ベンチでCPU側にとって無意味なループを省略させないとかかね

401 名前:デフォルトの名無しさん mailto:sage [2007/10/26(金) 18:43:50 ]
>>400
保証されない。
xが32bitだとして16bitのCPUなら、上位16ビットを代入した直後に
割り込みが入って上位16ビットを書き換えたらもうダメ。

402 名前:デフォルトの名無しさん mailto:sage [2007/10/26(金) 18:44:18 ]
×>>400
>>399

403 名前:デフォルトの名無しさん mailto:sage [2007/10/26(金) 21:02:16 ]
アトミックとvolatileは全然違う概念だと俺は信じてたけど…?

>>401
>>399は別に、xに2が設定されることが保障されると
言ってはいないと思う。

404 名前:デフォルトの名無しさん mailto:sage [2007/10/26(金) 21:30:30 ]
すると。

int X
X = 1+1;
dly_tsk(100); /* ウエイト */
if(X==2)
これはXは必ずしも真とはいえないのと同じか・・・?(割り込みで値なんていくらでも変更できるので)
volatileは最適化の抑止であって値の保証とは違うと思うが。
それともなんか俺、頭がおかしいのか?

最適化といえば、よくあるのがF-ROMのライトシーケンスやイレースシーケンスとかなんか同じアドレスに0xAAだの0x55だの書くから
最適化されるとうまく動かなくなるね。

ちなみに組み込みをやるとハードがらみで泣かされることがしばしば。
センサ情報で何度泣かされたか。ノイズで何度泣かされたか。静電気で・・・

405 名前:デフォルトの名無しさん [2007/10/26(金) 21:31:10 ]
setjmpとallocaって、呼び出しの前後順によってはlongjmpが
おきた時に何か問題おきるかな?



406 名前:デフォルトの名無しさん mailto:sage [2007/10/26(金) 23:03:52 ]
自信を持っては言えないのだが、多分volatileがあることで、
(処理系の詳細ではなく仕様で定められたセマンティクスの範囲内でも)
実装可能になる並列データ構造とかは存在するんではなかろうか?

407 名前:デフォルトの名無しさん mailto:sage [2007/10/26(金) 23:11:46 ]
ハードの熱で泣かされたことが……

408 名前:デフォルトの名無しさん mailto:sage [2007/10/26(金) 23:15:14 ]
>>405をおながいします。
allocaでずれたスタックポインタlongjmpで先祖がえりしてしまうような
ことは無いのか、どうなんでしょう?

409 名前:デフォルトの名無しさん mailto:sage [2007/10/26(金) 23:15:59 ]
スタックポインタ「が」longjmp

410 名前:デフォルトの名無しさん mailto:sage [2007/10/26(金) 23:24:37 ]
>>401
そんなあなたに sig_atomic_t

411 名前:デフォルトの名無しさん mailto:sage [2007/10/26(金) 23:28:54 ]
allocaがなんなのか知ってる?

412 名前:デフォルトの名無しさん mailto:sage [2007/10/26(金) 23:33:53 ]
void *p;
int result;

result = setjmp();
if (!result) {
 p = alloca(256);
 hoge(); /* hoge calles longjmp, NO RETURN */
 /* NOT REACHED HERE */
}

/* ここで p の指す先は大丈夫か? */

ということ?

413 名前:デフォルトの名無しさん mailto:sage [2007/10/27(土) 00:21:05 ]
>>412
そうそんな感じです。C言語として保証されてるのかな?と
ふと思ったので。

414 名前:デフォルトの名無しさん mailto:sage [2007/10/27(土) 00:39:46 ]
allocaは標準Cで既定されている関数ではないから、実装依存としか言いようがない。

415 名前:デフォルトの名無しさん mailto:sage [2007/10/27(土) 00:40:12 ]
alloca は C の標準関数じゃないので・・・



416 名前:デフォルトの名無しさん mailto:sage [2007/10/27(土) 00:45:12 ]
ああそうなんだ。知らなかったっす。どうもありがとう。

417 名前:デフォルトの名無しさん mailto:sage [2007/10/27(土) 01:48:57 ]
>>410
それがはC標準関数ではない
標準ではない型を別途定める必要があること自体C標準ではできないことの証明

418 名前:デフォルトの名無しさん mailto:sage [2007/10/27(土) 02:26:56 ]
sig_atomic_t は <signal.h> で定義されてる ANSI C 標準の型ですが何か?

419 名前:デフォルトの名無しさん mailto:sage [2007/10/27(土) 02:45:54 ]
関数ではないなw

420 名前:デフォルトの名無しさん [2007/11/05(月) 22:32:44 ]
規制中につき携帯から失礼します。
2バイト文字の文字コードを持つint型の変数があるときに
この変数の文字コードに該当する文字を取得しようとしたのですが
char型にぶちこもうとしたら1バイトずつに分けられて格納されて、wcharを使っても分けられてしまうようなのですが
どうにか2バイトまとめて一つの文字コードだと判断させる方法はないでしょうか?

421 名前:デフォルトの名無しさん mailto:sage [2007/11/05(月) 22:37:42 ]
Java の char と違って、ふつ〜 C の char は 8 ビットだからどうにもならない

422 名前:デフォルトの名無しさん mailto:sage [2007/11/05(月) 22:40:31 ]
sage忘れたorz

423 名前:デフォルトの名無しさん mailto:sage [2007/11/05(月) 22:52:09 ]
>>419
フイタw

424 名前:デフォルトの名無しさん mailto:sage [2007/11/05(月) 22:58:14 ]
>>420
何言ってるのか良く分からん。

>wcharを使っても分けられてしまうようなのですが
この部分を検証したコードと実行結果plz

425 名前:デフォルトの名無しさん [2007/11/06(火) 00:29:42 ]
scanfを使って整数型の変数に1〜100の値を入力された時のみ
続く処理をして、それ以外は再度入力を促すプログラムを作ってます。

入力された値のエラーのチェックにはどんな処理が必要か
わからないので教えてください。

あと数値を入力してEnterを押して実行したあとに
前回入力した数値が残ったままになっているのを
消すにはどうすればいいですか?



426 名前:425 [2007/11/06(火) 00:32:34 ]
スレ間違いすいません
初心者いってきます

427 名前:デフォルトの名無しさん mailto:sage [2007/11/11(日) 14:29:16 ]
typedef struct _target

428 名前:デフォルトの名無しさん mailto:sage [2007/11/11(日) 14:42:22 ]
>>427 そんなところに予約識別子使うやつ死ねって思う。

429 名前:デフォルトの名無しさん mailto:sage [2007/11/11(日) 19:55:32 ]
>>428
構造体タグは独立した名前空間だから別にいいんじゃね?
C++に移植したときにはまらないとも限らんが。

430 名前:デフォルトの名無しさん mailto:sage [2007/11/11(日) 20:09:22 ]
ダメなんだぜ。
7.1.3 Reserved identifiers
> - All identifiers that begin with an underscore are always reserved for use as identifiers
> with file scope in both the ordinary and tag name spaces.

431 名前:デフォルトの名無しさん mailto:sage [2007/11/15(木) 10:35:25 ]
>>430
俺が訳してやるぜ

アンダースコアから始まる識別子を使うな、どアホ

432 名前:デフォルトの名無しさん [2007/11/15(木) 12:01:23 ]
pc11.2ch.net/test/read.cgi/tech/1194016813/328-334
> 加減演算子
>
> ポインタオペランド及びその結果の両方が同じ配列オブジェクトの要素、又は
> 配列オブジェクトの最後の要素を一つ越えたところを指している場合、演算に
> よって、オーバーフローを生じてはならない。それ以外の場合、動作は未定義
> とする。

これ見て思ったんだけど、たとえばメモリ空間がアドレス 0x0000-0xffff の環境で、
メモリ空間の終端 16 バイトに char a[16] が割り当てられて a が 0xfff0 を指す場合、
a + 16 は 0x0000 に対応することになると思うんだ。で、さらにその実装が 0x0000 を
ヌルポインタとしていた場合、 a + 16 == 0 が真になるようなことがあるかもしれない。

これはオーバーフローっぽいから配列をそんなところに割り当てないようにしないと
いけないのかもしれないけど、実際のところ a + 16 はオブジェクトを指す必要がないから
ヌルポインタになったところで問題ないのかもしれないとも思う。

配列の最後の要素を一つ越えたところを指しているポインタがヌルポインタと
等しくなるような実装って、規格の範囲内なのかね?

433 名前:デフォルトの名無しさん mailto:sage [2007/11/15(木) 12:15:14 ]
だめなんじゃない?

6.5.8 Relational operators の 5
>If the expression P points to an element of an array object
>and the expression Q points to the last element of the same array object,
>the pointer expression Q+1 compares greater than P.

char a[16] に対しては a < a+16 が成立しなきゃいけないらしい

434 名前:デフォルトの名無しさん mailto:sage [2007/11/15(木) 12:29:14 ]
効率の面から全然現実的じゃないけど、大小比較においてはぬるぽを特別扱いして
最強としておけば a < a + 16 の要件は満たせる。明示的なぬるぽとの比較は
未定義動作だから、これによって規格から外れるということにはならない・・・かなり苦しいな。

435 名前:デフォルトの名無しさん mailto:sage [2007/11/15(木) 12:40:35 ]
ってことは、アドレス 0 をヌルポインタに使っている実装で、 ROM や RAM が
アドレス空間の終端にあるようなときは、ちょっと気をつけて終端ぴったりにオブジェクトが
配置されないようにする必要がある、ってことになるのかな?

リンカに指示するマッピングで終端1ワード(バイト?)ぐらい予約にしてやればいいのか。



436 名前:デフォルトの名無しさん mailto:sage [2007/11/15(木) 18:22:24 ]
>>434
>432のメモリモデルでユーザメモリ空間が0x8000以上なら、
ポインタ演算を符合付き整数で行なう実装ができそうだ。

437 名前:デフォルトの名無しさん mailto:sage [2007/11/15(木) 21:26:34 ]
いかれた規格野郎のために、これでまともに動作すれば規格合致で portable なことが保証できる、規格の限界を極めた変態処理系とかできないもんかな。

438 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 00:07:49 ]
#include <stdio.h>
int main (void)
{
int a,b;
scanf("%d",&a);
scanf("%d",&b);
printf("2番目の数みたい%d1番目の数みたい%dこれはどこ?%d");
return 0;
}
printfの%dはいったいどうった仕様でよまれているんでしょうか?

439 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 00:15:32 ]
www.linux.or.jp/JM/html/LDP_man-pages/man3/printf.3.html

440 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 00:19:39 ]
>>438
printfの%dは、何を表示したいか最後に引数で指定しないとだめ

printf("2番目の数みたい%d1番目の数みたい%dこれはどこ?%d", a, b, 42);

441 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 01:10:04 ]
>>439>>440
どうもです。
よくわからんかったんですけど、stdinのなかでも読んでるのかな?
いつもは書式("%d",a)見たいな感じで使ってるんですけど、
前問題で
scanf("%d",&a);
printf("あなたが入力したのは%dです");
があって、aの値が出力されたのでなんでだろうと思って聞いてみました。

442 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 01:39:09 ]
未定義動作なので、単なる偶然。
たぶんスタックが関係してるとおもうけど。


443 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 11:11:03 ]
> よくわからんかったんですけど、stdinのなかでも読んでるのかな?

違います。第2引数以降に順番に対応します。%d に限らずみんなそうです。
>>440 の例をよく吟味してみてください。

> 前問題で
> scanf("%d",&a);
> printf("あなたが入力したのは%dです");
> があって、aの値が出力されたのでなんでだろうと思って聞いてみました。

の答えが >>442 で、何かの問題としてそういうプログラムがあったのだったら、
それは誤植かバグ。

444 名前:デフォルトの名無しさん [2007/11/20(火) 12:26:52 ]
10から99までの10進数の数値を1の桁と10の桁に分けたい場合
どうすればいいでしょう?

例えば56を5と6に分けたい場合、どうすればいいのでしょう?

445 名前:デフォルトの名無しさん mailto:sage [2007/11/20(火) 12:28:12 ]
56 / 10 → 5
56 % 10 → 6



446 名前:デフォルトの名無しさん mailto:sage [2007/11/20(火) 12:36:56 ]
long型なんですが・・・

447 名前:デフォルトの名無しさん mailto:sage [2007/11/20(火) 12:37:44 ]
あっ間違えました。ありがとうございました

448 名前:デフォルトの名無しさん mailto:sage [2007/11/20(火) 12:48:28 ]
↑のような質問のスレではないので次の質問を書く人は注意

449 名前:デフォルトの名無しさん mailto:sage [2007/11/20(火) 15:42:08 ]
>>448
これがゆとり世代と言うもの


450 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 14:20:32 ]
予約識別子について質問です。
今までは
・下線 _ で始まり英小文字 a-z が続く一般識別子は global namespace で予約済み
というルールから、
type_t function( type_t _parameter ){ return _parameter; };
のような仮引数名は予約識別子ではなかったはず(FAQでも同様の回答)なのですが、
「C99 では Reserved identifiers が『マクロ名を含む』になったから global namespace で #define _paramete されてたら仮引数名も上書きされない?」
と指摘されました。
恥ずかしながら、規格を読んでみても具体的に何が変わったのか私には分かりませんでした。

「今後は避けられるなら避けた方がよい」のは前提として、
既にある _parameter のような仮引数名は今でも安全なのでしょうか?

451 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 14:33:26 ]
処理系が _parameter というマクロを定義可能になったから、
処理系が _parameter というマクロを定義していた場合に
その引数の _parameter という部分が置き換えられるかもしれない、
という話じゃね。

C99 に対応してないだろう ANSI C/C++ 辞典を見ると、
下線で始まるマクロ名は全て予約識別子らしいから、
今でも問題があるかと。

下線を付ける場合は、普通後ろに1つだけ付ける。

452 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 15:06:34 ]
>>450
規格の範囲内で問題ないかといえば、問題ない。 >430 にあるように、タグ名を含む
ファイルスコープの識別子として予約されていて、マクロにも使える下線+英大文字とは
区別されている。

ただし、そういう指摘を受けて規格の詳細を見直さないと自信が持てないような
状況を避けるため、はじめから下線始まりの識別子を使わないようにしたほうがいい。

453 名前:デフォルトの名無しさん [2007/11/27(火) 15:48:32 ]
C言語ってさ、他のソースに定義してある関数とか引数ちがってmainの中で使ってもコンパイルエラーださないじゃん。

あと、まったく未定義な関数つかっても他のソースにあるかもしれないからとかいう理由でコンパイルエラーだしてくれないじゃん。
とても不便だよね。

なんで、コンパイラはそれくらいのことをしてくれないのかな?別に面倒じゃないと思うんだけど。

454 名前:デフォルトの名無しさん mailto:sage [2007/11/27(火) 15:57:06 ]
>>453
大抵のまともなコンパイラなら、(宣言が見つからないと言う理由で)警告を出してくれると思います。
尤も、中にはデフォルトではその警告を出さないコンパイラもありますが。

詳しいことは、それぞれのコンパイラのスレなどでどうぞ。

455 名前:デフォルトの名無しさん mailto:sage [2007/11/27(火) 16:03:46 ]
>>453 のような話題のためのスレではないので次の質問を書く人は注意



456 名前:453 [2007/11/27(火) 16:14:35 ]
>>454 thx 俺のコンパイラがいけんのか。そうか。

やっぱ高いのじゃないとだめだね。なんでも。貧乏人は苦労するよ。

>>455 C言語のコンパイラ全部そうだとおもってたんだよ。俺はトウシロウだから。

457 名前:デフォルトの名無しさん mailto:sage [2007/11/27(火) 16:24:38 ]
>>456
ここはコンパイラの使い方のスレではないので程々に。
今無料で利用できるコンパイラの多くが警告を出せると思うので、調べてみてください。

458 名前:デフォルトの名無しさん mailto:sage [2007/11/27(火) 16:51:26 ]
gccなら-Wall つけとけ

459 名前:デフォルトの名無しさん mailto:sage [2007/11/27(火) 20:47:25 ]
本当はリンカの仕事だからな

460 名前:デフォルトの名無しさん mailto:sage [2007/11/28(水) 00:49:19 ]
リンカにその情報は渡らんだろ。渡せるように作れるが。

461 名前:デフォルトの名無しさん mailto:sage [2007/11/28(水) 07:14:08 ]
>>460
Cの関数はデフォルトだと内部リンケージだったっけ?

462 名前:デフォルトの名無しさん mailto:sage [2007/11/28(水) 10:45:04 ]
いいえ。

463 名前:デフォルトの名無しさん mailto:sage [2007/11/28(水) 20:12:34 ]
strcpy と wcscpy のようにアルゴリズムが殆ど同じだが扱う型・定数が微妙に違う関数を同時に実装する必要があるとします。
実装しなければならない数は 2〜3 型 x 30〜40 関数ぐらいとします。

このような場合、

/* strcpy.cpp */
char *strcpy( char *dst_, const char *src_ ) {
char *head = dst_; while( '\0' != (*dst_++ = *src_++) ){ /* nop */; } return head;
}
/* wcscpy.cpp */
wchar_t *wcscpy( wchar_t *dst_, const wchar_t *src_ ) {
wchar_t *head = dst_; while( L'\0' != (*dst_++ = *src_++) ){ /* nop */; } return head;
}

と一つづつ同じような関数を書いていくのと

/* fallthrough */

464 名前:デフォルトの名無しさん mailto:sage [2007/11/28(水) 20:13:12 ]
アルゴリズムだけ書いた

/* template/strcpy.cpp */
#ifdef XCS_IS_CHAR
#define char_t char
#define xcscpy_ strcpy
#define text_( text ) text
#endif

#ifdef XCS_IS_WCHAR
#define char_t wchar_t
#define xcscpy_ wcscpy
#define text_( text ) L ## text
#endif

/* strcpy, wcscpy */
char_t *xcscpy_( char_t *dst_, const char_t *src_ ){
char_t *head = dst_; while( text_('\0') != (*dst_++ = *src_++) ){ /* nop */; } return head;
}

のようなテンプレートを用意して

/* strcpy.cpp */
#define XCS_IS_WCHAR
#include <template/strcpy.cpp>

/* wcscpy.cpp */
#define XCS_IS_CHAR
#include <template/strcpy.cpp>

と読み込ませるので、どちらが良いと思いますか?
あるいは、もっと良い方法がありますか?

465 名前:デフォルトの名無しさん mailto:sage [2007/11/28(水) 20:16:38 ]
ちなみに発想は VC++ の crt のソースからです。

>>464 の訂正 /* ファイル名が逆 */

/* strcpy.cpp */
#define XCS_IS_CHAR
#include <template/strcpy.cpp>

/* wcscpy.cpp */
#define XCS_IS_WCHAR
#include <template/strcpy.cpp>



466 名前:デフォルトの名無しさん mailto:sage [2007/11/28(水) 20:16:53 ]
C++だったら、C++の関数テンプレート機能を使う方がいい

template<typename T> T *xcscpy( T *dst_, const T *src_ ){
T *head = dst_; while( 0 != (*dst_++ = *src_++) ){ /* nop */; } return head;
};

467 名前:デフォルトの名無しさん mailto:sage [2007/11/28(水) 20:21:52 ]
>>466
でもここは残念ながらCのスレ






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<146KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef