1 名前:デフォルトの名無しさん mailto:sage [2010/01/29(金) 23:15:45 ] エスケープシーケンスやWin32APIなどの環境依存なものでもOK。 ただしその場合、質問者は必ず環境を書きましょう。 ※sage禁止です(と代々スレに書いてありますが自己判断で)。 【前スレ】 【初心者歓迎】C/C++室 Ver.70【環境依存OK】 pc12.2ch.net/test/read.cgi/tech/1258873470/ 【アップローダー】(質問が長い時はココ使うと便利) kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm codepad.org/ (コンパイルもできるし出力結果も得られるのでお勧め) ◆ソースのインデントについて 半角空白やTABでのインデントはスレに貼ると無くなります。 そのため、アップローダーに上げるのも手ですが直接貼る場合は、 全角空白か に置換すると見栄えだけはよくなります。
2 名前:デフォルトの名無しさん [2010/01/30(土) 00:01:59 ] codepad ttp://codepad.org/ 長いソースを貼るときはここへ!
3 名前:デフォルトの名無しさん [2010/01/30(土) 14:18:17 ] 相談があるので乗ってほしい。 ターゲットは組み込みプロセッサで、メモリマップドレジスタのマクロ宣言で困ってる。 あるレジスタREG_Aがあって、そのレジスタの - アドレスは 0X12345678、 - レジスタは4バイト長、 - 内部の値は符号無し整数 とする。コンパイラの整数長が4バイトとすると、こういう場合次のようなマクロ定義が定石になってる。 #define REG_A *( volatile unsigned int * ) 0x12345678 こうすると、REG_Aはプログラム中で変数のように使える。当然だけど、この「変数」へのアクセスはレジスタへのアクセスになる。で、困っているのは次のような場合。あるレジスタREG_Bがあって、そのレジスタの - アドレスは 0XFFFF1234 - レジスタ、整数型、ポインタ型はそれぞれ4バイト長 - 内部の値は関数へのポインタ - 関数は void () つまり、引数も取らず、何も返さない。関数へのポインタ。こういうレジスタは割り込みハンドラのアドレス指定時に使う。 gccを使って試しているんだけど、どうしてもうまくいかない。今はあきらめて*( volatile unsigned int *)としてプログラム中でキャストしているんだけど、気持ちわるい。だれか教えて。試験に使っているプログラムはこんな感じ。 codepad.org/iid7z1G1
4 名前:デフォルトの名無しさん mailto:sage [2010/01/30(土) 14:30:36 ] volatileって関数の返却値に使っても有効なの? 規格ではどうなってるんだろ
5 名前:デフォルトの名無しさん mailto:sage [2010/01/30(土) 14:37:29 ] 関数ポインタを使うときは、ちょっとでもわかりにくくなったら 必ずtypedefを使うようにするのが鉄則だと思う。 typedef void vfn_t(void); #define REG_B (*(volatile vfn_t *) 0x11223344) とか。 いや、これが正常に動くか、そもそも望みのものなのかも知らないけどね。
6 名前:デフォルトの名無しさん mailto:sage [2010/01/30(土) 18:40:07 ] >>5 typedef void (*vfn_t)(void) で正解だな。
7 名前:デフォルトの名無しさん mailto:sage [2010/01/30(土) 21:15:46 ] >>3 >>今はあきらめて*( volatile unsigned int *)としてプログラム中で >>キャストしているんだけど それでいいんじゃない?別に気持ち悪くない
8 名前:デフォルトの名無しさん [2010/01/30(土) 22:16:06 ] >>4-7 ありがとう、提案された方法を試したあとに結果を報告する。 >>4 関数の返却値に使いたいんじゃなくて、レジスタの中身がvolatileであることを 宣言したい。だけどそのやり方がわからなくて、貼り付けたコードはめちゃめちゃに なってる。 >>7 折角だしプログラムの中でいちいちキャストしたくないんだよ。キャストって、 この場合は正しく宣言していれば不要だし、間違った型の代入を防ぐことも できる。
9 名前:デフォルトの名無しさん [2010/01/30(土) 22:26:18 ] サンキュー、 >>6 の言うとおりにしたら動いたよ。 ソースはこれ。コンパイル結果を読みやすいようにレジスタアドレスを10進に変えてある。 codepad.org/SBJtR0is GCCのコンパイル結果。見事にREG_A、REG_Bへの代入に成功している。 .loc 1 10 0 movl $12345678, %edx movl $foo, %eax movl %eax, (%edx) .loc 1 11 0 movl $12345674, %edx movl $foo, %eax movl %eax, (%edx) .loc 1 12 0 addl $4, %esp popl %ecx popl %ebp leal -4(%ecx), %esp ret 本当にありがとう。
10 名前:デフォルトの名無しさん mailto:sage [2010/01/30(土) 23:46:26 ] 敢えて一行で書くならこうかな? #define REG_B (*(void(*volatile*)()) 0XFFFF1234)
11 名前:デフォルトの名無しさん mailto:sage [2010/01/31(日) 01:04:51 ] >>9 #define の値は括弧で囲っといたほうがいいよ。 それから引数無しの引数リストに void を入れるかどうかはそろえといたほうがいいよ。 C なら必須。
12 名前:デフォルトの名無しさん mailto:sage [2010/01/31(日) 09:19:40 ] 任意のクラスのオブジェクトの情報をまるごとバイナリファイルに保存・復元みたいなことはできるんだろうか?
13 名前:デフォルトの名無しさん mailto:sage [2010/01/31(日) 09:40:27 ] >>9 代入がアトミックになってないぞ mutexか何かでバリアしておいた方が良くないか?
14 名前:デフォルトの名無しさん mailto:sage [2010/01/31(日) 09:56:49 ] >>12 シリアライズで出来るんじゃない? 自分はやったことないけどね
15 名前:デフォルトの名無しさん mailto:sage [2010/01/31(日) 10:32:39 ] >>12 boost::serializationかな
16 名前:デフォルトの名無しさん mailto:sage [2010/01/31(日) 11:24:01 ] >>12 もうまさにboost::serializationだな。
17 名前:デフォルトの名無しさん mailto:sage [2010/01/31(日) 17:21:13 ] >>12 保存中の進捗表示はboost::progress_displayにお任せ!
18 名前:デフォルトの名無しさん [2010/01/31(日) 18:06:17 ] 環境ですが、 OSはWindouwsXP コンパイラ名はMicrosoft VisualC++2008 Express Edition 言語はC です。 解決できず困っている事があるので、よろしくお願いします。 質問 → kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10478.txt
19 名前:デフォルトの名無しさん mailto:sage [2010/01/31(日) 18:26:32 ] WindowsでフリーでVC++ライクの総合環境ってなんか無い?
20 名前:デフォルトの名無しさん mailto:sage [2010/01/31(日) 18:42:37 ] >>19 VC++ EE
21 名前:デフォルトの名無しさん [2010/01/31(日) 23:02:34 ] void (*handle) (); int address = 0x00000; handle = (void (*) () )address; このコードがよくわかりません。 関数ポインタを宣言していることはわかるんですが、3行目のキャストが何を意味しているかが不明です。教えてください
22 名前:デフォルトの名無しさん mailto:sage [2010/01/31(日) 23:05:05 ] 代入先を考えろ
23 名前:デフォルトの名無しさん mailto:sage [2010/01/31(日) 23:21:49 ] >>21 関数へのポインタにキャストしているだけです。 void (*x)(); という宣言が理解できるのであれば、それから識別子をとりのぞくと、そのままキャストに使う書き方になるだけです。
24 名前:デフォルトの名無しさん mailto:sage [2010/01/31(日) 23:45:44 ] ちょうど関数ポインタの話題が出てるので聞きたいんだけど、 クラス内でstaticな2次元配列の関数ポインタを扱いたいときってどうすればいいんだろうか。 class ObjectManeger{ public: static bool (*Collision[2][2])(const Object &a, const Object &b); static bool A(const Object &a, const Object &b){}; static bool B(const Object &a, const Object &b){}; static bool C(const Object &a, const Object &b){}; static bool D(const Object &a, const Object &b){}; }; bool (ObjectManeger::*Collision[2][2])(const Object &a, const Object &b); って感じの所まではたぶん合ってると思うんだけど・・・。 2×2の配列にABCDの各関数を入れたいんだ。
25 名前:デフォルトの名無しさん mailto:sage [2010/01/31(日) 23:48:12 ] >>21 単に警告でないように強制型合わせしているだけ 違うものを強制挿入する時よくやる
26 名前:デフォルトの名無しさん mailto:sage [2010/01/31(日) 23:56:43 ] >>24 static な関数だと ObjectManeger::* じゃなくてただの * でいいよ。 っていうかコンパイルしてみればいいじゃない。
27 名前:デフォルトの名無しさん mailto:sage [2010/02/01(月) 00:02:47 ] >>26 外部シンボルは未解決だ、って怒られるんだ。 あと、ABCDの各関数を初期化時に入れるのはどうやってやるのか・・・。 色々試したんだけど、コンパイルでエラーの嵐で分からないんだぜ・・・。
28 名前:デフォルトの名無しさん mailto:sage [2010/02/01(月) 00:07:11 ] class Object; class ObjectManeger { public: static bool (*Collision[2][2])(const Object &a, const Object &b); static bool A(const Object &a, const Object &b) { return true; } static bool B(const Object &a, const Object &b) { return true; } static bool C(const Object &a, const Object &b) { return true; } static bool D(const Object &a, const Object &b) { return true; } }; bool (*ObjectManeger::Collision[2][2])(const Object &a, const Object &b) = { &ObjectManeger::A, &ObjectManeger::B, &ObjectManeger::C, &ObjectManeger::D };
29 名前:デフォルトの名無しさん mailto:sage [2010/02/01(月) 00:08:26 ] 関ポはtypedef これ、常識ね
30 名前:デフォルトの名無しさん mailto:sage [2010/02/01(月) 00:10:17 ] bool (*ObjectManeger::Collision[2][2])(const Object &a, const Object &b) = { { &ObjectManeger::A, &ObjectManeger::B }, { &ObjectManeger::C, &ObjectManeger::D } }; ミスった
31 名前:デフォルトの名無しさん mailto:sage [2010/02/01(月) 00:18:05 ] >>30 通った! ありがとう! そう書けばよかったのか・・・。 >>29 可読性的な意味で、なのかな。 確かに見づらい・・・。
32 名前:デフォルトの名無しさん mailto:sage [2010/02/01(月) 00:56:26 ] >>14-16 virtual 使ってるクラスでもできる?
33 名前:デフォルトの名無しさん mailto:sage [2010/02/01(月) 01:20:53 ] class ObjectManager { typedef bool collision_t(const Object& lhs, const Object& rhs); static collision_t *Collision[2][2]; ... }; ObjectManager::collision_t ObjectManager::Collision[2][2] = { &ObjectManager::A, ... }; て感じか。 メンバ関数ポインタじゃないから、そんなに複雑な見た目にはならないかな。
34 名前:デフォルトの名無しさん mailto:sage [2010/02/01(月) 08:01:37 ] 関数ポインタって typedef void (*func_ptr_t)(void); func_ptr_t fp = &func; だけじゃなくて typedef void func_t(void); func_t * fp = &func; でも通るんだ はじめて知ったよ これって標準?
35 名前:デフォルトの名無しさん mailto:sage [2010/02/01(月) 09:09:07 ] >>34 うん。
36 名前:デフォルトの名無しさん mailto:sage [2010/02/01(月) 21:48:30 ] javaだとIDEの補完機能を使うとimport *を勝手に書いてくれるけど、 C++のIDEはそんな機能がないのかな? いちいち、#inluce <*>って書くのが面倒くさい それとも、Qt Creatorは新しいから無いのかな?
37 名前:デフォルトの名無しさん mailto:sage [2010/02/01(月) 22:10:21 ] だから無理してC/C++なんかやらなくていいよ ずっとJavaで良いじゃん
38 名前:デフォルトの名無しさん mailto:sage [2010/02/01(月) 22:10:24 ] >>36 C++はないよ C# ならある
39 名前:デフォルトの名無しさん mailto:sage [2010/02/01(月) 22:17:59 ] >>38 わかったよ、ありがとう
40 名前:デフォルトの名無しさん mailto:sage [2010/02/02(火) 10:59:32 ] C++では普通の関数は使わないのですか? 普通の関数の代わりに、staticのメンバ関数を使うのが常識なのですか?
41 名前:デフォルトの名無しさん mailto:sage [2010/02/02(火) 11:08:43 ] >>40 べつにクラスを使わないんだったらバシバシ普通の関数も使うよ ただクラスを定義しとくとデバッグがめっちゃ楽になんのよ
42 名前:デフォルトの名無しさん mailto:sage [2010/02/02(火) 11:15:45 ] 普通の関数ももちろん使うよ algoritmヘッダなんかには普通の関数もたくさん入ってる(ほとんどテンプレート関数だけど) もちろん普通の関数を使うところで staticメンバ関数を使っても問題は起こらないから すべてstaticメンバ関数で統一したければすればいい むしろ可視性の操作とかネストクラスとかできることが増えるから staticメンバのほうが俺はいいと思う
43 名前:デフォルトの名無しさん mailto:sage [2010/02/02(火) 16:28:40 ] template <typename T> class Hoge と言うクラスがあるとき 実装をcppファイルに記述するには明示的実体化するしかないのでしょうか? .hファイルに実装を記述するととても見苦しい状態になってしまうのですがどうにかならないでしょうか
44 名前:デフォルトの名無しさん mailto:sage [2010/02/02(火) 16:30:30 ] コンパイラによります
45 名前:デフォルトの名無しさん mailto:sage [2010/02/02(火) 16:32:45 ] 使用環境はVS2005standard editionです
46 名前:デフォルトの名無しさん mailto:sage [2010/02/02(火) 18:38:51 ] >>43 仕方がありません Comeau C++を買いましょう
47 名前:40 mailto:sage [2010/02/02(火) 19:25:32 ] >>41-42 ありがとうございます static関数はクラスに属していますが、それ以外は普通の関数と同じなのですか?
48 名前:デフォルトの名無しさん mailto:sage [2010/02/02(火) 20:33:42 ] クラスの名前空間に属して、そのクラスのprivate/protectedメンバを触れること以外は同じと見て差し支えない 細かい違いはあるけど
49 名前:デフォルトの名無しさん mailto:sage [2010/02/02(火) 20:36:50 ] >>43 いいんじゃね boostの.hppってっ拡張子は 実装も含んでるヘッダだよ、っていうような意味なんじゃないかね
50 名前:デフォルトの名無しさん mailto:sage [2010/02/02(火) 20:39:53 ] >>48 thx
51 名前:デフォルトの名無しさん mailto:sage [2010/02/02(火) 21:45:20 ] >>49 Boost FAQには以下のようにあるけど。 >なぜ Boost のヘッダファイルはどれもこれも .hpp を使い、 .h や拡張子なしにしないのですか? >ファイルの拡張子は、人間とコンピュータプログラムの両方にそのファイルの "型" を伝えるものである。 >'.h' という拡張子は C のヘッダファイルで用いられており、 C++ のヘッダファイルに関して間違ったことを伝えてしまう。 >拡張子無しのものを用いると何も伝わらず、型を断定するためにファイルの中身を調べることを強制する。 >'.hpp' を使うことで、そのファイルが C++ のヘッダファイルであることを明確に特定することができ、 また実際に使う際にもきちんと動作する。 (Rainer Deyke)
52 名前:デフォルトの名無しさん mailto:sage [2010/02/02(火) 22:00:10 ] >>51 つまりC++は静的型付け言語だから、 同じように型の発想をしよう、ということか。 ・・・それって守らなきゃダメなん? Boost以外でも守られるのが標準的なC++の文化なの?
53 名前:デフォルトの名無しさん mailto:sage [2010/02/02(火) 22:24:15 ] 拡張子なんてただの飾りだから何でもいいよ .fuckとか.javaとか.exeとか付けるのも自由だ
54 名前:デフォルトの名無しさん mailto:sage [2010/02/02(火) 22:30:12 ] >>53 まあ自由だけど、それをまねした 小学生がぶん殴られたら可哀想じゃないか!
55 名前:デフォルトの名無しさん mailto:sage [2010/02/02(火) 22:32:54 ] The Loki Library を見てみたら、ふつーに.hだったわ。
56 名前:デフォルトの名無しさん mailto:sage [2010/02/02(火) 22:34:27 ] .exe とか .lnk とか拡張子によってはシステムべったりだから飾りじゃすまないな
57 名前:デフォルトの名無しさん mailto:sage [2010/02/02(火) 22:50:13 ] ゲームのパラメータをファイルに置いておきたいんですが c++から使えて暗号化もできるシンプルなデータベースってありますか?
58 名前:デフォルトの名無しさん [2010/02/02(火) 22:53:42 ] Linuxにてgprofでプロファイルを見てみたのですが、全関数の処理の合計時間が実測した時間よりも短くなっていました。 この差分は何に起因するものなのでしょうか?
59 名前:デフォルトの名無しさん mailto:sage [2010/02/02(火) 22:57:07 ] >>58 cputime と usertime の差?
60 名前:デフォルトの名無しさん mailto:sage [2010/02/02(火) 23:12:30 ] >>57 www.moongift.jp/2010/01/sqlcipher/ これとかどうだろう
61 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 05:05:32 ] gccでAみたいに書くとstrict aliasing rules警告されるんで、 Bみたいに書いたんだけど、これって正しい、というか、 -fno-strict-aliasingを指定した場合と同じ意味になるって保証されてる? struct Vec { int x, y, z; }; int data[3][3] = {{0,1,2},{3,4,5},{6,7,8}}; int main() { Vec* v0 = (Vec*)data; // A 警告される Vec* v1 = (Vec*)(void*)data; // B 警告されない return 0; }
62 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 06:37:25 ] 警告残した方が後々の為に良い気も
63 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 06:39:24 ] >>61 基本的にstrict aliasing ruleに対する違反は キャストでは解決できないと思った方がいい じゃあどうすればいいの?ってところでは GCC3.3.0以上なら__attibute__((may_alias))っていうのがある けど、そのコードはダーティすぎるからそこから直した方がいい
64 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 09:35:07 ] namespaceとはどういうときに使用するのですか?
65 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 09:42:43 ] >>64 名前衝突の可能性を最小限にしながら、面倒なプリフィックス付けもしたくないとき。
66 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 10:13:04 ] めんどうっていうけど std_hogeもstd::hogeも変わらねーよ
67 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 10:24:18 ] じゃあインテリセンスで一覧表示させたい場合
68 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 10:34:05 ] >>66 たとえば関数 hoge の宣言や定義で同じ名前空間にある名前を何度も使うことを考えると 話が違ってくるはず。 std_result std_hoge(std_arg1 a1, std_arg2 a2) { std_detail d; std_impl(d, a1, a2); } namespace std { result hoge(arg1 a1, arg2 a2) { detail d; impl(d, a1, a2); } }
69 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 10:43:42 ] DQN的プログラミングにnamespaceは不要
70 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 11:32:37 ] DLLとかでエクスポートするときに邪魔なんだよ名前空間 いちいちラップしないといけない
71 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 11:42:06 ] クラス内の複数箇所でstd::out_of_range("適当なエラーメッセージ") このまま文字列リテラルがコード各所に散らばるのは気持ち悪いので 1.あらかじめエラーメッセージをメンバ変数に持たせておく 2.例外を投げるメンバ関数を用意する 3.std::out_of_range("適当なエラーメッセージ")をマクロ定義しておく どれがスマートな方法でしょうか?
72 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 11:54:58 ] 俺はマクロかなぁ const文字列にしてもいいけどマクロのが楽じゃわい
73 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 12:09:13 ] void check_range(int min, int max, int value) { if (value < min || value > max) throw std::out_of_range("〜"); }
74 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 12:14:27 ] >>73 それじゃどこからエラー出たか特定できないじゃん
75 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 12:18:23 ] どのみち例外に行番号情報は含まれないから、元から特定できないと思うけど
76 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 12:28:21 ] __FILE__と__LINE__をパラメータで渡せばいい
77 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 14:24:53 ] 別に何も対策はしないな それで問題が出るわけじゃないし
78 名前:デフォルトの名無しさん [2010/02/03(水) 15:43:49 ] C++ で継承不可能なクラスを宣言することはできますか? C# や Java の static class みたいに。
79 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 15:49:27 ] 残念なことにできません (C#やJavaのsealedやfinalのことだよね?) 仮想関数にあたるものにvirtualを付けないことで これ以上継承しないでね、という意思表示にすることぐらいしか 現状できないと思う ただ、次期C++だとたぶんあるんじゃないかな
80 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 15:52:22 ] 例外をマクロ化するのは良いアイデアだなとおもったけど 標準例外のコンストラクタに__LINE__と__FILE__を渡す方法を思いつかなくてガッカリ・・・ どういうマクロにすれば良いでしょうか?
81 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 16:00:32 ] class out_of_range_with_line_number : public std::out_of_range { ........... };
82 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 16:13:05 ] 行番号とかよりも どの関数から/どのデータが原因で投げられたのか、といった情報を入れたほうがいいんでないかい out_of_rangeなら、どの配列からout_of_rangeが出たのかによって それが分かるような例外クラスを作ってrethrowするとか
83 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 16:37:42 ] つ boost::exception
84 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 17:48:55 ] >>81 >>83 やっぱり継承するなりなんなりするしかないか
85 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 18:37:02 ] >>78 デストラクタを private にしてみるとか。 class Hoge { private: ~Hoge() {} };
86 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 18:50:11 ] まともに使えねえよ
87 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 19:06:09 ] C++0xの[[final]]も継承禁止じゃないしな
88 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 19:08:30 ] iface *create(...) { class local : public iface { ... }; return new local(...); } 制限はあるけどこれでfinalだよ
89 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 20:52:17 ] 教えて下さい。 今お仕事のデバッグ用にSDカードのセクタをFATではなく セクタ直接アクセスするコードを今使ってます。 そのソフトでドライブ選択をGetDriveType()でリムーバブルディスクのみを 選択できるようにしておるのですが、これではカードリーダーライターに 刺さったディスク全て選択できてしまいます。(例えばCFとかUSBメモリとか) 自分だけで使う場合は注意すればいいだけなのですが、チームで使ってるんで できればドライブ選択をSDカードONLYにしたいと思っているのですが、 どのようなコードにすればいいでしょうか? 環境 WindowsXP Microsoft VisualC++ 6.0 MFC
90 名前:デフォルトの名無しさん mailto:sage [2010/02/04(木) 00:22:22 ] >>71 どの方法にも何のメリットも感じられない。 そのままにしとくのが一番スマートな気がする。 >>80 #define OUT_OF_RANGE(what) (std::out_of_range(std::string(__FILE__":"BOOST_PP_STRINGIZE(__LINE__)": ") + (what)))
91 名前:デフォルトの名無しさん mailto:sage [2010/02/04(木) 01:59:50 ] >>62-63 ありがとう。できるだけ根本的に修正するようにしてみる。 ついでに、このコードについても教えてくれないか。 ttp://codepad.org/novJOf5Z これ、仕事で使ってるgcc4.1.1とcodepad(gcc4.1.2)では警告されるのに、cygwinのgcc4.3.2だと、 -fstrict-aliasingと-Wstrict-aliasingを指定しても警告されないんだ(-Wstrict-aliasing=2を加えれば警告される)。 このへんの動作って4.1.2以降で変更されてる? gccのchangesを見たけど、関係ありそうなのは4.2の The C++ frontend now also produces strict aliasing warnings when -fstrict-aliasing -Wstrict-aliasing is in effect. くらいしか見つけられんかった。
92 名前:デフォルトの名無しさん mailto:sage [2010/02/04(木) 05:32:31 ] >>91 どうしてそんな碌でも無いコードばかり書くんだ… GCCのchangelogに書いてあるのは大きなものだけだから 知らないうちに内部の動作が少々変わることはありうるよ 無印の-Wstrict-aliasingで警告がでないのが正しいかはわからん そこらへんの加減はgccの中の人にしかわからんだろうから…
93 名前:デフォルトの名無しさん mailto:sage [2010/02/04(木) 09:36:50 ] #include <iostream> #include <fstream> #pragma pack(push, 1) struct POD { int a, b; char str[5]; int x, y, z; }; #pragma pack(pop) void test(POD &pod) { std::cout << "a: " << pod.a << std::endl; std::cout << "b: " << pod.b << std::endl; std::cout << "str: " << pod.str << std::endl; std::cout << "x: " << pod.x << std::endl; std::cout << "y: " << pod.y << std::endl; std::cout << "z: " << pod.z << std::endl; }
94 名前:デフォルトの名無しさん mailto:sage [2010/02/04(木) 09:37:33 ] void save(POD &pod) { std::ofstream out("test.bin", std::ios::binary); out.write((char*)&pod, sizeof(POD)); } void load(POD &pod) { std::ifstream in("test.bin", std::ios::binary); POD tmp; in.read((char*)&tmp, sizeof(POD)); pod = tmp; }
95 名前:デフォルトの名無しさん mailto:sage [2010/02/04(木) 09:39:19 ] int main(void) { POD pod1 = {1, 2, "test", 3, 4, 5}; test(pod1); save(pod1); POD pod2 = {0}; load(pod2); test(pod2); return 0; } 上記のコードは自分のマシンだと期待通りに動いてるようなんですが ほかのマシンに移植しても大丈夫でしょうか?
96 名前:デフォルトの名無しさん mailto:sage [2010/02/04(木) 09:44:54 ] intの奇数番地アクセスに問題ないCPUだったら、大丈夫かも
97 名前:デフォルトの名無しさん mailto:sage [2010/02/04(木) 10:01:24 ] >>96 レスありがとうございます 念のためpack(push, 4)にしてみます
98 名前:デフォルトの名無しさん mailto:sage [2010/02/04(木) 10:07:15 ] 移植性考えるなら stdint.hを読み込んで int を int32_t とかに
99 名前:デフォルトの名無しさん mailto:sage [2010/02/04(木) 12:44:50 ] >>98 レスありがとうございます バイト数も揃えてみます vc++にstdintが無いのが困りものですがvs2010にはあるようなので・・・
100 名前:デフォルトの名無しさん mailto:sage [2010/02/04(木) 13:21:04 ] >>92 >どうしてそんな碌でも無いコードばかり書くんだ… ごめんw 実は>>91 は、社内製コードでLoadFileAsync(const char* filename, void** buffer)っていうのがあるんだけど、 これがgcc4.1.1にしたら警告が出たので、調査用に書いたんだわ。 動作は、filenameを非同期にディスクから読み出して、読み出したメモリ領域のアドレスをbufferに返す。 非同期ロード用クラスでも作って、void**を置き換えればいいんだろうが、 既にあちこちで呼ばれてる関数だから手を出しづらいんだよね。
101 名前:デフォルトの名無しさん mailto:sage [2010/02/04(木) 16:21:27 ] >>99 ttp://www.kijineko.co.jp/node/63 こういうのがあるよ
102 名前:デフォルトの名無しさん mailto:sage [2010/02/04(木) 23:42:27 ] >>100 それでもその強引なキャストは要らんのでは? A a; void* p; f(&p); a.str = static_cast<char*>(p); もしかしてメモリ領域の確保も非同期なの?