トップページ⇒tech
1001コメント322KB

C++相談室 part90

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2011/07/17(日) 15:50:39.24
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレに
お願いします。

前スレ
C++相談室 part89
http://hibari.2ch.net/test/read.cgi/tech/1304410950/

このスレもよろしくね。
http://hibari.2ch.net/test/read.cgi/tech/1299218426/

ついでに壁紙にしてね。
http://www.research.att.com/~bs/Bjarne.jpg
0153デフォルトの名無しさん2011/07/24(日) 21:25:40.60
コンパイラはgcc(g++)です。
0154デフォルトの名無しさん2011/07/24(日) 22:22:56.68
関数ポインタをキャストということが、どれだけ異常な事態かわかってる?
0155デフォルトの名無しさん2011/07/24(日) 22:27:45.86
「関数ポインタのキャスト」は異常と言えば異常だが、正常でもある。>>152のは異常。
0156デフォルトの名無しさん2011/07/24(日) 22:34:50.10
>>154
わかってないですね
教えて頂けると嬉しいです。

>>155
friniedにした方が良いという事でしょうか?
0157デフォルトの名無しさん2011/07/24(日) 22:39:45.73
メンバー関数はptheadには渡せない。staticメンバー関数なら渡せる。
0158デフォルトの名無しさん2011/07/24(日) 22:44:02.88
http://www.atmarkit.co.jp/fdotnet/chushin/comparedataproc_01/comparedataproc_01_02.html
こういう話でC++がハブられるのは何故なんでしょう?
0159デフォルトの名無しさん2011/07/24(日) 22:48:36.12
人気言語じゃないから
0160デフォルトの名無しさん2011/07/24(日) 23:19:42.99
>>157
なので、関数ポインタの型キャストをしたのです。
警告がでますが、正常に動きます。
friendの方が良いということでしょうか?
0161デフォルトの名無しさん2011/07/24(日) 23:31:08.49
>>156
void(*a)() = (キャスト)printf;
a();
↑
何が起きるか考えてみな
0162デフォルトの名無しさん2011/07/24(日) 23:37:08.92
>>152が何をしたいのか理解できない俺はおかしいのか?
0163デフォルトの名無しさん2011/07/24(日) 23:38:46.98
スッドレという言葉が出てるのに想像できないのはおかしいね
0164デフォルトの名無しさん2011/07/24(日) 23:39:54.58
スッドレ!
0165デフォルトの名無しさん2011/07/24(日) 23:42:23.73
>>157
大抵の実装ではキャスト無しで通ってしまうが、ほんとうは extern "C" の付いてる
pthread の関数に extern "C++" な static メンバ関数へのポインタは渡せない。

>>160 キャストってのは↑の問題のことか?
よくわかんないからコピペ推奨。
0166デフォルトの名無しさん2011/07/24(日) 23:44:16.71
>>161
よくわかりませんね。

class A{
void *func(void *p);
};
pthread_create(NULL, NULL, reinterpret_cast<void* (*)(void*)>(&A::func), NULL);

において、
このキャストが悪い理由がわかりません。
結局、friendにした方が良いとおっしゃりたいんですかね?
0167デフォルトの名無しさん2011/07/24(日) 23:48:25.22
>>166
func を実行する相手がいないだろ
アクセス制御とは無関係な問題だ
0168デフォルトの名無しさん2011/07/24(日) 23:52:04.17
>>167
funcの実体がないという事ですか?
割愛したんですが、

xxx.h

class A{
void *func(void *p);
};

xxx.c
A::A(){
pthread_create(NULL, NULL, reinterpret_cast<void* (*)(void*)>(&A::func), NULL);
}

void *A::func(void *p){
return NULL;
}

取りあえず、クラスのメンバ関数にするか、frindでAにアクセスする方が良いかを聞きたいのですが…
0169デフォルトの名無しさん2011/07/24(日) 23:53:01.50
>>166
これはfriendとかそういう次元の話じゃないな
0170デフォルトの名無しさん2011/07/24(日) 23:53:42.08
>>169
では、funcがclass Aにアクセスするにはどうすればいいですか?
0171デフォルトの名無しさん2011/07/24(日) 23:55:14.54
>>170
pからアクセスすれば?
0172デフォルトの名無しさん2011/07/24(日) 23:55:41.27
>>171
すみません。
pってなんですか?
0173デフォルトの名無しさん2011/07/24(日) 23:57:46.90
void *func(void *p <- これ
pthread_createの第四引数にthis渡せば普通にAのメンバ呼べるでしょ
0174デフォルトの名無しさん2011/07/24(日) 23:58:14.76
>>170
func の実体じゃない、func の対象
クラスにアクセスって、自分が言ってることを冷静に考えてみな
0175デフォルトの名無しさん2011/07/24(日) 23:58:26.05
>>151
ライブラリ実装側が、個別の出入力ごとに事前操作と事後操作を入れられるようになる。
オブジェクトにすることで事後操作が正しく実行されることを想定できる。

こんなところかと。たぶん。
0176デフォルトの名無しさん2011/07/25(月) 00:00:29.18
>>173
やっと納得できる答えがありました。
どうもありがとうございます。
0177デフォルトの名無しさん2011/07/25(月) 01:03:21.26
なんかずれてる思考だな。この先苦労しそうな人。
ていうか、頭固すぎ。
0178デフォルトの名無しさん2011/07/25(月) 01:09:32.28
多重継承クラスのメンバポインタや
仮想関数のメンバポインタがからむと
発狂しそうだな、このお方

sizeof の違う reinterpret_cast とか平気みたいだし
0179デフォルトの名無しさん2011/07/25(月) 02:13:07.61
コードの書き方で、人生の心配までされたのは初めてだw
C++って最近暇つぶしに書き始めたばかりだから、先輩諸氏には到底及ばんと思う。


結局、ワーニングでるけどこれにしました。
pthread_create(NULL, NULL, reinterpret_cast<void* (*)(void*)>(&A::func), NULL);
privateにアクセス出来ないのは結構痛いので。
0180デフォルトの名無しさん2011/07/25(月) 02:15:20.64
sizeofが違っても、reinterpret_castしても大丈夫だと思うのだが…
陰口もいいけど、合理的な理由も付けて欲しいね
0181デフォルトの名無しさん2011/07/25(月) 02:19:59.36
>>179
それじゃやりたいことができないだろう。
A のインスタンスをスレッド内で作成できるなら別だが。
0182デフォルトの名無しさん2011/07/25(月) 02:25:42.82
>>179
こいつ何もわかってなくて泣いた
0183デフォルトの名無しさん2011/07/25(月) 02:32:54.63
>>179
メンバポインタからやり直した方がいいよ
0184デフォルトの名無しさん2011/07/25(月) 02:33:01.77
>>180
確かに sizeof は本質ではないが、サイズとは無関係に reinterpret_cast 自体が大丈夫じゃない。
大丈夫だと思うならまずその理由を言ってみろよ。
0185デフォルトの名無しさん2011/07/25(月) 02:38:01.05
>>179
お前それで正常に動いたか?
0186デフォルトの名無しさん2011/07/25(月) 02:40:15.38
>>159
確かに…
0187デフォルトの名無しさん2011/07/25(月) 03:57:15.70
>>184
ダメな理由を述べよ

てか、教えないがグダグダ言われてもな…
嫌なら答えなきゃ良いのに、腐った死体ばかりだなw
0188デフォルトの名無しさん2011/07/25(月) 03:58:16.97
君たち偉大な技術者には敵わないから、おおめに見てくれや。
0189デフォルトの名無しさん2011/07/25(月) 04:02:08.08
教えてもここにいる技術者に突っ込まれるしな
相手に語らせればつついて遊べるし
0190デフォルトの名無しさん2011/07/25(月) 04:03:53.12
>>185
動かなかった。
スレッドは実行されるが、メンバ変数にアクセスしたところで落ちた。
勉強して出直すわ。

friendにして、明日試してみる。
0191デフォルトの名無しさん2011/07/25(月) 04:11:34.03
それにしてもメンバ関数を無理やりキャストして使うってすごい発想だな
0192デフォルトの名無しさん2011/07/25(月) 04:19:24.48
そうか?
むしろ、メンバ変数を参照するには、それしか思いつかんかった。
0193デフォルトの名無しさん2011/07/25(月) 04:33:01.56
>>190

>friendにして、明日試してみる。

結果報告ヨロ
メンバ関数ポインタという物を全く理解してないのがこれでわかるな・・・
0194デフォルトの名無しさん2011/07/25(月) 04:34:44.69
boost::thread tr(boost::bind(&A::func, this, NULL));
もうこれでいいよ
0195デフォルトの名無しさん2011/07/25(月) 05:28:32.37
簡単に考えてみようじゃん?
メンバ関数は中で this ポインタを使えるじゃん?
hoge.Save(); って呼び出すと、メンバ関数Saveの中で this(= hogeのアドレス)が使えるじゃん?
ってことはメンバ関数は裏で hoge(インスタンス)のアドレスが勝手に渡されてるってことじゃん?
ってことは普通の関数とメンバ関数は別物ってことになるじゃん?
0196デフォルトの名無しさん2011/07/25(月) 06:18:53.11
理解させるだけ無駄だな
0197デフォルトの名無しさん2011/07/25(月) 06:28:49.43
A::funcはスタック上にvoid*とthisが積まれていると想定しているのに対して、pthreadは
void*しか積んでないのでおかしな事になる。(thisには多分pthread_createルーチン内の
リターンアドレスが入っていると思う)
スタックの清掃は呼び出し側で行っているようなので問題ない様に見えるけど、
やってる事はスタックオーバーフローと大して変わらない

0198デフォルトの名無しさん2011/07/25(月) 06:43:38.13
std::cout << reinterpret_cast<int>(&A::func) << std::endl;
面白いからやってみろよ
0199デフォルトの名無しさん2011/07/25(月) 07:17:15.23
>>180,187
N3290 5.2.10 [expr.reinterpret.cast] p6 より。
"The effect of calling a function through a pointer to a function type that is not the same
as the type used in the definition of the function is undefined."

これまで流れを見るに、これで理解してもらえるとは思わないが。
0200デフォルトの名無しさん2011/07/25(月) 07:42:00.94
自分で考えない奴が理解できるわけがない
0201デフォルトの名無しさん2011/07/25(月) 08:04:45.64
なんか、早朝から俺を懸命に貶す作業をしてる奴ら乙ww
「相談室」というスレタイで来たのに、ベテランの公開オナニー場とは詐欺なスレだなw

>>193
間違いなく、ただの関数ポインタって思ってるからな。
昨日の結果を鑑みると、何か間違ってるようだが。。
盆休みにでも、徹底して勉強したい。

>>197
解説ありがとう。
唯一、技術的にCプログラマな俺にもわかるように説明してくれたのはあんただよ。
0202デフォルトの名無しさん2011/07/25(月) 08:10:28.84
>>199
せっかく出典出してもらったのに悪いが、君の予想通りわからないっぽい。
せめて日本語なら…
0203デフォルトの名無しさん2011/07/25(月) 08:18:19.63
>>187
reinterpret_cast はどこで覚えたの?

どういう解説したら「reinterpret_castしても大丈夫」「ダメな理由を述べよ」なんて
発想になってしまうのか興味があるな。
0204デフォルトの名無しさん2011/07/25(月) 08:35:58.71
>>201
> 「相談室」というスレタイで来たのに、ベテランの公開オナニー場とは詐欺なスレだなw
書籍等で学んでいることが前提だよ。その上でわからない場合の相談室。一から十までこのスレで学ぶ気か?
キミは基本を全くわかっていないのに、どこから仕入れてきた知識かしらんけど、見よう見まねでfriendとか言い出してる。
これじゃ、C++の初心者でも簡単に弄れる。弄ってるのはベテランじゃなくて初心者だろう。

面倒くさいから正しい書き方教えてやる。なぜこうするのかは書籍で学べ。

#include <pthread.h>
class A {
private:
void member1() { }
public:
static void* thread_func(void *data) {
A &self = *reinterpret_cast<A *>(data);
self.member1();
....
return NULL;
}
};
void aaaa()
{
pthread_t th;
A a;
pthread_create(&th, NULL, A::thread_func, &a);
}
0205デフォルトの名無しさん2011/07/25(月) 09:59:39.11
>>204
> 面倒くさいから正しい書き方教えてやる。なぜこうするのかは書籍で学べ。
「正しい」ねぇ・・・

> A &self = *reinterpret_cast<A *>(data);
static_cast だろ。

> pthread_create(&th, NULL, A::thread_func, &a);
>>165

あと pthread_create() のエラー処理な。
0206デフォルトの名無しさん2011/07/25(月) 10:23:44.88
>>205
カルシウム足りてないようだな。

ポインターの変換には例外を設けずreinterpret_castを用いる方が自然。
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1120
0207デフォルトの名無しさん2011/07/25(月) 10:32:25.61
>>206
リンク先が全然根拠になってない件。
少なくとも C++2003 では標準の範囲外なわけだ。
さらに C++2011 で変換自体が認められたとしても変換後の値自体は
unspecified で、動作は保証されない。
全然自然じゃない。

暗黙変換の逆変換は C++1998 からずっと static_cast の役目。
0208デフォルトの名無しさん2011/07/25(月) 11:25:24.22
>>201
一生Cから出てこないでほしいな
0209デフォルトの名無しさん2011/07/25(月) 11:29:44.20
>>207
void*からオブジェクトのポインタへの変換後の動作が保証されないのは
static_castも同様。つーか保証できるわけがない。
だからこそ、reinterpret_castでいいじゃんという話がでてきてる。
0210デフォルトの名無しさん2011/07/25(月) 12:56:40.78
ビット列を変えずに型だけ変わったことにしたければ reinterpret_cast
暗黙変換の逆なら const_cast や dynamic_cast という場合もある
上記いずれにもあたらない「明示的な型変換」がしたいとき static_cast

よって 204,206 vs 205=207 は 204,206 の勝ち

# この法則にも穴があるが今の流れとは関係ないので放置
0211デフォルトの名無しさん2011/07/25(月) 13:14:51.06
とりあえず全てstatic_castを使って対応出来ない場合のみ
他のキャストを使用するって方針なのかもよ
reinterpret_castだと(やるかどうかは別として)間違えてvoid*以外を渡してもコンパイルエラーにならないし
0212デフォルトの名無しさん2011/07/25(月) 14:37:25.35
>>211
まあreinterpret_cast使うなら任意の不完全型でもいいからなw
voidは「static_castでも変換できる不完全型」なのでせっかくだから俺はこのstatic_castを選ぶぜ!ってやつがいてもおかしくない。例えば俺とか
0213デフォルトの名無しさん2011/07/25(月) 14:40:52.64
僕はCスタイルキャストちゃん!
0214デフォルトの名無しさん2011/07/25(月) 14:50:31.93
【初心者歓迎】C/C++室 Ver.75【環境依存OK】
http://hibari.2ch.net/test/read.cgi/tech/1299218426/
0215デフォルトの名無しさん2011/07/25(月) 16:20:33.28
>>211
テンプレートを作ってコンパイルエラー検出。
template <class T>
T hoge_cast(void*p)
{
return reinterpret_cast<T>(p);
}
0216デフォルトの名無しさん2011/07/25(月) 20:29:47.21
>>203
入門書にかいてあったよ。
結構平気でvoid *に値突っ込んだり、取り出したりしてたから

>>204
そうカリカリするなよ。
一応、入門書は走破して、実際にコードを書き始めたわけさ。
スレタイに入門者・初心者お断りといれればどうよ?
あと、サンプルありがとな。
早速試すわ。

>>208
お前の人生には迷惑かけないから、ゆるしてちょ

0217デフォルトの名無しさん2011/07/25(月) 20:30:22.17
喧嘩はやめてくれ。たのむ

ttp://ideone.com/BlmAq

サンプル書いてみました。「メンバへのポインタ」でググるといいかも

実際に書いてみると、自分の知識もずいぶんと曖昧だと思いました
21行目でreinterpret_cast<int>(this)がエラーになる理由と
67行目の&演算子を外すとエラーになる理由がよく分からないです
0218デフォルトの名無しさん2011/07/25(月) 20:49:28.30
>>217
散々叩かれた俺が言うべきか分からんけど、
一つ目は(64bit cpuでは)intではケタがたりないのでは?
0219デフォルトの名無しさん2011/07/25(月) 20:50:50.27
>>217
staticメンバ関数ってようは普通の関数だからthisとか使えない
0220デフォルトの名無しさん2011/07/25(月) 22:05:29.74
禿本よめば一発で済むことをまあgdgdと長いこと・・・
0221デフォルトの名無しさん2011/07/25(月) 22:06:38.05
>>217
pthreadの件については、戻り値と引数が同じ関数なら型キャスト出来ると思っていた。
少なくとも今まで上手くいかなかった事がないので、
生涯わからんと思うけど、
C++において、メンバ関数の型キャストは危険と覚えておくわ。
0222デフォルトの名無しさん2011/07/25(月) 22:49:13.11
ttp://ideone.com/nG9M6

普通のポインタ:
メモリ上の直接のアドレス

メンバへのポインタ:
インスタンスの先頭アドレスからのオフセット、
なのでインスタンスと一緒に使わないと意味がない

普通の関数ポインタを、メンバへのポインタに reinterpret_cast するのは
危ないのではないかと思う
0223デフォルトの名無しさん2011/07/26(火) 00:51:50.21
>>209
> void*からオブジェクトのポインタへの変換後の動作が保証されないのは
> static_castも同様。つーか保証できるわけがない。

なんでそう思ったの?

static_cast の動作として T* → void* という標準変換の逆変換が含まれることは
きちんと規格で定められているよ。 N3290 だと 5.2.9 p7 で。
0224デフォルトの名無しさん2011/07/26(火) 00:59:17.78
>>210
> ビット列を変えずに型だけ変わったことにしたければ reinterpret_cast

reinterpret_cast でビット列が変わらないと期待するコードに移植性は無いよ。
5.2.10 p3
[ Note: The mapping performed by reinterpret_cast might, or might not, produce
a representation different from the original value. ?end note ]


ポインタを別のポインタ型にキャストして、元に戻してから使う限りは static_cast も
reinterpret_cast も同程度の保証があるけど、 >>204 について言えば最初の変換が
暗黙変換なのだから戻すのは static_cast じゃないといけない。

戻すのに reinterpret_cast を使うのなら、最初の変換も reinterpret_cast でなければ
ならない。
pthread_create(&th, NULL, A::thread_func, reinterpret_cast<void*>(&a));
0225デフォルトの名無しさん2011/07/26(火) 03:24:22.80
>>223
> なんでそう思ったの?
当たり前だろ。void *として渡されてたポインタが変換先のオブジェクトへの
ポインタであったことなんか保証できないんだから。

>>224
暗黙変換の逆変換がstatic_castで出来るというだけで、暗黙変換の逆変換を
static_castでやらなければいけないなんて、どこにも書いていない。
0226デフォルトの名無しさん2011/07/26(火) 04:12:55.78
>>225
> 当たり前だろ。void *として渡されてたポインタが変換先のオブジェクトへの
> ポインタであったことなんか保証できないんだから。

そこの保証が無い場合はどのキャスト使おうがアウトなんで話してもしょうがないでしょ。

> static_castでやらなければいけないなんて、どこにも書いていない。

static_cast では、暗黙変換の逆変換ができると定められている。
reinterpret_cast では、暗黙変換の逆変換ができると定められていない。
(変換自体はできるが値が unspecified になる)

どっちを使うべきか、もうわかるよね?
0227デフォルトの名無しさん2011/07/26(火) 07:34:46.38
> reinterpret_cast では、暗黙変換の逆変換ができると定められていない。
> (変換自体はできるが値が unspecified になる)
妄想規格 wwww
0228デフォルトの名無しさん2011/07/26(火) 08:52:13.99
>>227
ちがうの?
5.2.10 [expr.reinterpret.cast] paragraph 7 (>>206 のリンク先)に unspecified って
書いてあるみたいだけど。
0229デフォルトの名無しさん2011/07/26(火) 09:11:57.88
>>228
The result of any other such pointer conversion is unspecified.
これら以外のポインター変換の結果はunspecified
0230デフォルトの名無しさん2011/07/26(火) 10:04:46.66
「確かに、フジテレビの方針は目に余るものがあります。ペ・ヨンジュンブームのころから
韓流ドラマをやたら放送したり、女子フィギュアでは浅田真央よりキム・ヨナに寄せた
報道をして批判を浴びたりしたことがありましたが、最近ではさらに拍車がかかっている
ようで、社内にも微妙な雰囲気が漂っています」(フジテレビ関係者)

フジテレビや産経新聞は「フジサンケイグループ」の傘下だが、同グループのサンケイ
スポーツからは4月に韓国エンターテインメント情報のタブロイド誌「韓Fun(カンファン)」が
創刊されるなど、今年に入って"韓流押し"に本腰を入れてきているという。

「フジは他にも、今年4月に渋谷と恵比寿に同時オープンしたK-POPの常設公演会場
『Kシアター』に出資。系列の音楽出版会社はKARAらK-POPアーティストの版権を
買いまくっている。七夕に放送された同局の情報番組では『少女時代のように足が
綺麗になりますように』『KARAのライブに行けますように』などと書かれた短冊を
映り込ませ、女子アナたちもことあるごとに韓国旅行の魅力をPR。まるで韓国国家の
宣伝企業と化している状態ですよ」(スポーツ紙デスク)

そうしたメディアと視聴者との温度差が露見した形となった今回の騒動。現在のような、
キー局による露骨な"利益誘導型"の放送が続けば、さらなるテレビ離れが進むことは
避けられないだろう。

http://news.livedoor.com/article/detail/5732069/
0231デフォルトの名無しさん2011/07/26(火) 12:36:47.82
>>229
これら = reinterpret_castでT1 *→T2 *→T1 *とすると元の値に戻りますよーとかnullはどのポインタに変換してもnullですよーなど
でしょ?

んでその「これら」には
暗黙の変換でT1 *→void *に変換して
そのあとreinterpret_castでvoid *→T1 *に変換すると元の値に戻りますよってのが含まれてるの?
ってのが>>228の言いたいことなんじゃね?


今ちょっと調べられないけどどうなの?
0232デフォルトの名無しさん2011/07/26(火) 14:28:30.70
>>231
半端な知識でいいがかりつけてきた>>205が引けなくなって粘着してるだけだから気にすんな。
「これらの変換」が「T1*をT2*に変換したものを元に戻す」の事で、それ以外はunspecifiedと
いうのならば、↓これがunspecifiedという事になってしまう。

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

int bbb(sockaddr *sa);

int aaa(struct sockaddr_in *sin)
{
return bbb(reinterpret_cast<struct sockaddr*>(sin));
}

すなわち、「これらの変換」とはその前(スタンダードタイプでかつT2のアライメント要求が
厳しくない、またはどちらかがvoid)の変換も含む。
0233デフォルトの名無しさん2011/07/26(火) 14:55:48.31
>>232
> いうのならば、↓これがunspecifiedという事になってしまう。

C++03 までは unspecified なコードだね。

> すなわち、「これらの変換」とはその前(スタンダードタイプでかつT2のアライメント要求が
> 厳しくない、またはどちらかがvoid)の変換も含む。

で、 >>204 のコードでは void* data → A* だから「どちらかがvoid」に含まれ、
その結果は static_cast<A*>(static_cast<void*>(data)) となる、つまり
static_cast<A*>(data) になる、と C++11 では新たに規定されることになった。
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#658
0234デフォルトの名無しさん2011/07/26(火) 15:27:51.46
>>222
そのメンバポインタの話じゃないだろ

>>226
> static_cast では、暗黙変換の逆変換ができると定められている。

いちいち突っ込むのもアホくせえほど無茶苦茶やなw
0235デフォルトの名無しさん2011/07/26(火) 15:34:21.30
>>234 N3290 5.2.9 p7 で定められてるらしい(>223)ぞ。
0236デフォルトの名無しさん2011/07/26(火) 15:35:52.25
>>232はC++03でも正しい。
「voidのアライメントなんて定義されてねー」と言いがかりつけてくるのがいるので、
voidが特記された。

5.2.10 p7
A pointer to an object can be explicitly converted to a pointer to an object of
different type. Except that converting an rvalue of type 懼pointer to T1懼
to the type 懼pointer to T2懼 (where T1 and T2 are object types and where the
alignment requirements of T2 are no stricter than those of T1) and back to its
original type yields the original pointer value, the result of such a pointer
conversion is unspecified
0237デフォルトの名無しさん2011/07/26(火) 15:40:14.59
化けた。
ま、>>233が規格理解してない半可通という事が証明されてしまったわけだ。w

5.2.10 p7
A pointer to an object can be explicitly converted to a pointer to an object of
different type. Except that converting an rvalue of type "pointer to T1" to the
type "pointer to T2" (where T1 and T2 are object types and where the alignment
requirements of T2 are no stricter than those of T1) and back to its original type
yields the original pointer value, the result of such a pointer conversion is
unspecified.
0238デフォルトの名無しさん2011/07/26(火) 15:41:41.85
>>233
C++03 では void* → A* の変換自体が認められていない。
unspecified 以前にコンパイルが通らない可能性がある。
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1120
02392382011/07/26(火) 15:44:19.26
>>237
void* は "pointer to an object" ではなくてですね。

> ま、>>233が規格理解してない半可通という事が証明されてしまったわけだ。w
お前もな。
0240デフォルトの名無しさん2011/07/26(火) 15:47:31.99
>>236
ねー、 >>232 ってキャストした後元に戻してないんだけど、なんで大丈夫なの?
0241デフォルトの名無しさん2011/07/26(火) 15:57:47.31
そもそもなんでこんなに reinterpret_cast が大好きなんだろう?
危険性や移植性が増えるだけだろうに。
0242デフォルトの名無しさん2011/07/26(火) 15:58:30.32
>>235
template <typename a>
int b(int c)
{
a d;
d = c; //暗黙変換
return N3290_cast<int>(d); //ふーん、すごいなあ・・・
}
0243デフォルトの名無しさん2011/07/26(火) 15:59:40.73
>>238-239
> C++03 では void* → A* の変換自体が認められていない。
> void* は "pointer to an object" ではなくてですね。
そういう言いがかり付けてくる奴がいるから「どっちかがvoid」が追加されたんだよ。w
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1120

>>240
bbb()はconnect(2)のようにstruct socksaddr*を引数に取る関数。
bbbの内部(共通部分に書かれてるタイプみて)で戻す。
0244デフォルトの名無しさん2011/07/26(火) 16:01:49.75
>>241
それじゃお前は↓このように書け。大変だな。www

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int bbb(sockaddr *sa);

int aaa(struct sockaddr_in *sin)
{
return bbb(static_cast<struct sockaddr*>(static_cast<void*>(sin)));
}
0245デフォルトの名無しさん2011/07/26(火) 16:37:33.92
C++形式のキャストそのものが嫌いな俺はどうしたらいいんだぜ
0246デフォルトの名無しさん2011/07/26(火) 16:38:59.49
よく首にならないな
0247デフォルトの名無しさん2011/07/26(火) 17:42:24.37
>>241
今は>>231の2段落目 "んでその「これら」には……が含まれてるの?" のYes/Noを議論してるので
それが実際にコーディングする上でミスを誘いやすいか否かはまた別の問題として扱ったほうがいいんじゃないかな
0248デフォルトの名無しさん2011/07/26(火) 17:49:56.19
>>237
でもその文面に void の特記が含まれてないお
というか現行標準の 5.2.10/7 には未だ void の特記は
含まれてないと思うお
0249デフォルトの名無しさん2011/07/26(火) 18:57:35.15
>>237
>>232の例がC++03でunspecifiedだと>>233が言いがかり付けてきたから、
C++03(>>236)を引用した。

>>232-233はvoid*とは直接関係ないから。文脈読めない人は引っ込んでなよ。
0250デフォルトの名無しさん2011/07/26(火) 19:25:55.62
アンカー間違えた

>>248
>>232の例がC++03でunspecifiedだと>>233が言いがかり付けてきたから、
C++03(>>236-237)を引用した。

>>232-233はvoid*とは直接関係ないから。文脈読めない人は引っ込んでなよ。
0251デフォルトの名無しさん2011/07/26(火) 21:26:03.86
ttp://ideone.com/NlHSk

確かに 5.2.10p7 の Converting... の文だけでは
A* => void* => A* のような void* を含む変換では、元に戻る確証が得られないような気がする

ただ、最初の文によると void* を経由して static_cast すれば、reinterpret_cast が実現できるので
reinterpret_cast<A*>( reinterpret_cast<void*>( &A() ) )
は
static_cast<A*>( static_cast<void*>( static_cast<void*>( static_cast<void*>( &A() ) ) ) )
= static_cast<A*>( static_cast<void*>( &A() ) )   /* (!) */
と同じこと

そして、5.2.9p13 によれば、(!) の式は元の値に等しくなるとある

「ただ、…」以降の部分は、確証がもてんです
というか、実務で問題なく使えれば、もうそれでいいかなあ。。
0252デフォルトの名無しさん2011/07/26(火) 21:30:24.11
ああ、抜けがある。。ごめんなさい

void* gf( void* )
{
  A().operation();
  return NULL;
}

ところで、戻り値の NULL の型はどのような扱いになるんですか?
■ このスレッドは過去ログ倉庫に格納されています