C++相談室 part129at TECH
C++相談室 part129 - 暇つぶし2ch1005:デフォルトの名無しさん (オッペケ Sr17-bOuD)
17/03/30 21:03:14.83 dELrX4bqr.net
>クラスのメンバ関数を他の翻訳単位から見えなくしたいが明示的に名前つけたnamespaceにしたくないとき

始めて聞く珍妙な説だ
今日はクスリを飲み忘れているとか?

1006:デフォルトの名無しさん (ワッチョイ f359-HQfx)
17/03/30 21:21:56.78 8zS706yR0.net
>>982
a.cppとb.cppに同じ名前のクラスの定義を書いてしまい、さらに同じシグネチャのメンバ関数を書いてしまい、
しかし関数の中身が違うケースを考えると良い
これはリンク時にエラーになるか、杜撰な処理系だとどちらかが適当に呼ばれるという実害があり、
なおかつnamespaceでガードしない限り、ソースコードを弄る誰かが知らずに上のケースを実現してしまう危険性が残る

1007:デフォルトの名無しさん (ワッチョイ f359-HQfx)
17/03/30 21:26:32.64 8zS706yR0.net
スマン
誤: namespaceでガードしない限り
正: 無名namespaceでガードしない限り

名前付きnamespaceだとたまたま同じ名前を使われてしまう危険性が残る、

1008:デフォルトの名無しさん (ワッチョイ cf1f-jsM4)
17/03/30 21:26:49.87 gILJOuVy0.net
杜撰な処理系って具体的には何?

1009:デフォルトの名無しさん (ワッチョイ 038f-MCV6)
17/03/30 21:33:19.96 kb+hG/9a0.net
>>981
メンバは強制的に外部結合だからなあ
982は�


1010:Vャブじゃなくエトルフィンでも入れてるのかな



1011:デフォルトの名無しさん (ワッチョイ f359-HQfx)
17/03/30 21:34:44.32 8zS706yR0.net
>>985
Visual Studo 2010についてくるVC++とかいうマイナーな処理系
2008もそうだったような…

1012:デフォルトの名無しさん (ワッチョイ f359-HQfx)
17/03/30 21:39:33.97 8zS706yR0.net
次のコードで実験でくる。今日実験したら答えはcall_foo_a()もcall_foo_b()も30やったわ;
■ "a.cpp"
static foo {
 int func(int x, int y) { return x + y; }
};
void call_foo_a() {
 foo x;
 printf("%s: func(10, 20)=%d\n", __FUNCTION__, x.func(10, 20));
}

■ "b.cpp"
(a.cppと同じだが、foo::func()の中身を return x - y;に変えたやつ)

■ "main.cpp"
extern void call_foo_a();
extern void call_foo_b();
int main() {
call_foo_a(); call_foo_b();
}

1013:デフォルトの名無しさん (ワッチョイ f359-HQfx)
17/03/30 21:43:20.63 8zS706yR0.net
>>987
それはそうかもしれないが、無名namespaceのマングリング規則がトリッキーなのを
>>987は知らないんじゃないの;
いや詳しくは漏れも知らんが、

実際>>988のコードは"a.cpp"と"b.cpp"のfooをどっちも無名namespaceで囲えば正しく動く、
(call_foo_a()は30、call_foo_b()は-10となる、

1014:デフォルトの名無しさん (オッペケ Sr17-bOuD)
17/03/30 21:45:46.29 dELrX4bqr.net
>>983
>しかし関数の中身が違うケースを考えると良い

なるほど
それはクラスの定義自体が漏れていることが問題なのだが
なぜかメンバ関数の問題と勘違いしてしまったのだな

1015:デフォルトの名無しさん (ワッチョイ f359-HQfx)
17/03/30 21:49:03.80 8zS706yR0.net
>>990
何言ってるのかわからんが推測でレスするが、
メンバ関数を含まないクラスや構造体はリンクが必要なシンボルを生成しないから
同名のブツが複数の翻訳単位にあっても全く問題は無い(よってC言語はstaticだけで逝けた
つまりメンバ関数がこの話の本質だとわかっていない>>990のレスは大概だ、

1016:デフォルトの名無しさん (オッペケ Sr17-bOuD)
17/03/30 22:05:28.61 dELrX4bqr.net
>全く問題は無い

なるほど
ODR違反の未定義動作が問題無いと考えてしまうようでは致し方ない。
ちなみにC++にはテンプレートというものが有って
重複定義された型をパラメーターに持つテンプレートのインスタンスが問題を起こすと言うことには気づかなかったらしい

1017:デフォルトの名無しさん (ワッチョイ f359-HQfx)
17/03/30 22:15:12.42 8zS706yR0.net
>>992
ていうか話は逆で、>>988のようなケースがあるからODR制約という概念が生まれ、
無名namespaceは>>988のようなケースにおける解決策
(異なるマングリング名で異なる定義を識別するのだからODR制約には抵触しなくなる
ソースは脳内

>重複定義された型をパラメーターに持つテンプレートのインスタンスが問題を起こすと言うことには気づかなかったらしい
そりゃーODR制約違反のソースだとそうなるが、
無名namespaceで修正した>>988のfooでは起き得ない話、

1018:デフォルトの名無しさん (オッペケ Sr17-bOuD)
17/03/30 22:24:43.35 dELrX4bqr.net
>無名namespaceで修正した>>988のfooでは起き得ない話、

うーむ、二つ前の本人のレスは
無名namespaceで修正してなくても関数が無ければ全く問題ない
だったと思うのだが、もう忘れたのだろうか

1019:デフォルトの名無しさん (ワッチョイ f359-HQfx)
17/03/30 22:47:57.29 8zS706yR0.net
おk
無名namespaceで修正して「いない」>>998はODR違反だった気がするので
今謹んで訂正した、

1020:デフォルトの名無しさん (ワッチョイ d372-8ugA)
17/03/30 23:55:20.49 Plkrcx8f0.net
>>976
テンプレート関数だからでした。
想定されてたコンパイラのテンプレートの解釈がinclusion-modelってやつで、そのためでした。
ありがとうございました。

1021:デフォルトの名無しさん (ワッチョイ efc8-CrJt)
17/03/31 01:06:57.90 ryHYQIXS0.net
こういう糞議論してる間にほかの言語で着々とプロダクトが作られていくわけである。

1022:デフォルトの名無しさん (ワッチョイ f37a-QmV0)
17/03/31 01:09:12.34 UkLjKqcm0.net
記述の自由度が高いせいで全貌を知る者がほとんど居ない

1023:デフォルトの名無しさん (ワッチョイ cf36-FVbu)
17/03/31 01:14:14.24 RI1LGJ050.net
いや利用者の多いまともなプロダクトはc++で記述されているのが多いだろ。
LL言語のVMとかブラウザとかもそうだし

1024:デフォルトの名無しさん (ワッチョイ cf92-KV4R)
17/03/31 01:44:24.21 zbf3isLY0.net
パフォーマンスが重要な製品作る必要あるなら現状C++しか選択肢ないからね

1025:過去ログ ★
[過去ログ]
■ このスレッドは過去ログ倉庫に格納されています


最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch