C++相談室 part66
..
116:デフォルトの名無しさん
09/02/18 23:23:21
>>115さん
ありがとうございます。
名前空間を念頭に置いてコードを読み直してみます。
117:デフォルトの名無しさん
09/02/19 01:46:02
>>116
読むのはいいけど真似するなよ
118:デフォルトの名無しさん
09/02/20 01:09:13
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
119:デフォルトの名無しさん
09/02/20 01:12:34
すみません。
どなたかMPEG Audioのdist10というプログラム使ったことある方いらっしゃいませんか?
120:デフォルトの名無しさん
09/02/20 01:18:25
>>116
ヒント:スコープの概念。
static const int32_t var = 1; グローバルスコープ
namespace foo { static const int32_t var = 2; } fooスコープ
class hoge { public: static const int32_t var = 3; } hogeスコープ
::varは1
foo::varは2
hoge::varは3
121:デフォルトの名無しさん
09/02/25 11:10:00
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
122:デフォルトの名無しさん
09/03/13 20:52:41
throw new std::runtime_error("saji");
123:デフォルトの名無しさん
09/03/14 00:30:03
>>122
newされたstd::runtime_error *
だと!そんなもんthrowされたらまさにサジを投げるしかないな。
124:デフォルトの名無しさん
09/03/14 07:13:32
>>122
newはもちろんジョークだよな?
125:デフォルトの名無しさん
09/03/18 18:38:05
C++相談室 part67
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレに
お願いします。
前スレ
C++相談室 part66
スレリンク(tech板)
126:デフォルトの名無しさん
09/03/19 17:24:05
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
127:デフォルトの名無しさん
09/03/20 09:58:48
std::sort で std::vector の要素をソートしようとしています。std::sort の第三引数にでたらめな比較結果を返す
比較関数を与えるとvector の要素の一部がおかしな値に置き換わってしまい、場合によってはプログラムが
異常終了してしまう現象に悩まされています。問題を再現するプログラムを用意しました。
#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
int a[10] = {0, 0, 0, 1, 1, 1, 1, 0, 1, 1}, pos = 0;
class ComparisonFunc {
public: bool operator()(int i, int j) { return a[pos++] == 1; } };
void main() {
int t[] = {3, 5, 1, 4, 2}; std::vector<int> v(t, t+5);
std::sort(v.begin(), v.end(), ComparisonFunc()); assert(pos == 10);
for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it)
std::cout << *it << std::endl; }
このプログラムを実行すると第3要素の値がおかしくなります。VC++ 2008 Express Edition と
g++ 4.3.0 (MinGW) では一応実行が終了しますがIntel C コンパイラ 9.0 だと異常終了します。
環境は Windows XP SP3 (32ビット) です。「でたらめな比較結果を返す比較関数」を考えているのは、
ユーザが比較関数をスクリプト言語で定義できるシステムを作っているからです。operator() メソッドの
中でスクリプト言語で定義された比較関数を呼んで、その戻り値を operator() の戻り値として返す仕組みです。
そのためどんな比較関数が来てもプログラムが異常終了しないようにしたいと思います。どんな対策が
考えられるでしょうか? std::sort が比較関数の異常を検知して適当なところで処理を中断して例外でも
スローしてくれたらと思うのですがそこまで面倒は見てくれないようです。
128:デフォルトの名無しさん
09/03/20 10:47:27
>>127
std::sortに渡すコンパレータは辻褄のあった結果を返さないといけないと仕様で決められている。
そうでない場合の動作は未定義。
つまり、でたらめな結果を返す可能性のあるコンパレータはstd::sortには使えない。
ソート関数を自作するか、コンパレータを検証する関数を追加するしかないだろうね。
いずれにしても矛盾を検知しようと思ったら、O(n log n)では済まないと思う。
129:デフォルトの名無しさん
09/03/20 16:49:42
c++で作られたプログラムを逆アセンブルしてるんですが、アセンブリ言語について質問できるスレってありませんか?
130:デフォルトの名無しさん
09/03/20 17:16:32
このへんじゃね?
スレリンク(tech板)
131:デフォルトの名無しさん
09/03/20 17:20:20
C++で書かれたプログラムを逆アセ出来る人ってすごいなぁ。
意味不明じゃね?
132:デフォルトの名無しさん
09/03/20 17:30:16
逆アセするならそもそもアセンブラ理解しないと・・・。
80x86系統の命令コード表あると思うからそれ見ながら分解していけばいいかと
後単純なプログラムでコードがどうなるかをチェックし続けるっていうのが解析の基本><
133:デフォルトの名無しさん
09/03/20 17:34:18
>>130
ありがとうございました。
>>131
IDA pro とか簡単に逆アセンブルしてくれて、しかもグラフィカルに構造を表示してくれるので
あんまり知識が無くてもなんとなく分かります
しかも無料で使えるし。
ソフト自体が英語だしあんまり解説サイトとかが無いのが辛いですが・・。
134:131
09/03/20 19:47:12
IDA proってすげーー
135:デフォルトの名無しさん
09/03/20 19:56:39
引数オーバーロードによって戻り値を変えるプログラムが
g++ (1)3.3.6と(2)4.2.4で挙動が違います。
実行後 main戻り値が (1) => 2 / (2) => 1 となります。
NS1をNS2に書き換えると両方とも2が戻ります。
どっちの挙動が標準規格的には正しいですか?
//以下そのプログラム
#include <stdio.h>
namespace NS1 {
struct HUGA {};
}
namespace NS2 {
int get(...) { return 1; }
template <typename T>
int f() {
NS1::HUGA huga;
return get(&huga);
}
int get(NS1::HUGA * ) { return 2; }
}
int main() { return NS2::f<int>(); }
136:デフォルトの名無しさん
09/03/20 20:01:56
うーん。もしかして、Cのソースがあるものなら、直接アセンブラソース吐かせれば良いんじゃね?
バイナリを解析したいのならスマソ。
137:デフォルトの名無しさん
09/03/20 20:32:04
>>135
1
138:デフォルトの名無しさん
09/03/20 20:43:39
>>135
2
139:デフォルトの名無しさん
09/03/20 20:44:56
Visual C++2008では 2 になったけど
実際の動作は1にならないといけないみたいね。
vararg は言語によるすべての型チェックを無効にして
常にもっとも一致した型であることを強制するので
多重定義の解決では自動的に最優先になるみたい。
140:デフォルトの名無しさん
09/03/20 20:50:00
俺も気になってやってみた。
g++ (GCC) 3.4.5 (mingw special)では返り値は1で、
Borland C++ 5.5.1 for Win32では返り値は2だった。
…つまりg++ 4.2.4はちゃんと正しい進化を遂げているということか。
141:133
09/03/20 20:54:37
>>136
がっつりexeファイルです。
コマンドプロンプトで動く簡単(そう)なコンパイラがあるので、それを解析してデコンパイラを作ってみたくて・・。
にしても、2ちゃんねるのスレッド検索って、「アセンブラ」とか「アセンブリ」で検索すると結果が出るのに、
「アセンブ」で検索すると出ないんですね。ふしぎ!
142:デフォルトの名無しさん
09/03/20 21:02:36
(...)の絡む名前解決の定義ってISO/IEC 14882:2003にあるの?
もしなければ現段階では鼻から悪魔ってことになっちゃうんだけど
143:デフォルトの名無しさん
09/03/20 21:21:21
よこから質問なんですが
(...)
ってどうつかうんですか?
void func(int n, ...)
みたいのであればstdarg.hのマクロでやるのとは思うんですが
(...)みたいな...のみとはなんなんなんですか?
144:135
09/03/20 21:37:44
試してくれた人ありがとうございます。
>>139
...をvoid*にしても(2)はやっぱり1です。
ちなみにfの定義を非templateにすると両方とも
1になります。template関数が実体化されるときに
初めてオーバーロードの解決を行うっていう理屈で
あれば(1)が正しいような気もします。
ただそれはあまりにもマクロ的な発想だし(2)が
正しい?
NS1をNS2を書きかえると(2)が2に成るのも謎・・・。
145:デフォルトの名無しさん
09/03/20 23:05:11
URLリンク(page4.auctions.yahoo.co.jp)
146:デフォルトの名無しさん
09/03/21 00:58:20
>142
もちろんある。
っていうか、SFINAE を使う場合に用いられる場合がある。
>139
そして ... のオーバーロード解決の優先度は最低だ。
>常にもっとも一致した型であることを強制するので
これで優先されるのは関数テンプレートの時。
>144
> template関数が実体化されるときに
> 初めてオーバーロードの解決を行うっていう理屈で
> あれば(1)が正しいような気もします。
two phase lookup でぐぐれ。
dependent name の名前解決は実体化時まで遅延される。
nondependent name の名前解決は通常通り行われる。
get(&huga) は nondependent name なので名前解決は
通常通り行われ、この場合は get(...) に解決されるはず。
> 14882:2003
> 14.6 Name resolution/9
> If a name does not depend on a template-parameter (as defined in 14.6.2), a declaration (or set of declarations)
> for that name shall be in scope at the point where the name appears in the template definition; the
> name is bound to the declaration (or declarations) found at that point and this binding is not affected by
> declarations that are visible at the point of instantiation.
>
> 14.6.3 Non-dependent names/1
> Non-dependent names used in a template definition are
> found using the usual name lookup and bound at the
> point they are used.
147:デフォルトの名無しさん
09/03/21 01:07:07
補足。
>っていうか、SFINAE を使う場合に用いられる場合がある。
Modern C++ Design に優先順位が最低であることがポイントであるとした上で載ってるので
変態 templater にはそれなりに知られたテクニックだと思われ。
148:デフォルトの名無しさん
09/03/21 01:13:14
む・・・むずいw
149:135
09/03/21 01:20:21
>146
調べきれてないけど4.2.4の方が(規格的には)正しいような
気がしてきました。
NS2->NS1の書き換えはADLの関係でget(HUGA*)がヒット(2がかえる)。
だからget(HUGA*)を位置を変えずにNS1に持っていっても同様に
2がかえるのを確認しました。
get(void*)とget(HUGA*)をtemplate関数の特殊化とした場合
同様に2がかえる。
=> depend name?
それ以外の場合(オーバーロードの解決)は純粋に出現
順序で決定されると。
=> nondependent name?
もうちょっと調べてみます。ありがとうございます。
150:デフォルトの名無しさん
09/03/21 01:20:51
解決されるときに(...)の優先度が最低になるのが見付からないなぁ
ま事実だけ覚えときゃ十分か
151:デフォルトの名無しさん
09/03/21 01:48:31
>149
「NS2->NS1の書き換え」ってどこ書き換えたの?
テンプレート引数 T に依存するかどうかが dependent name かどうかの判断なので、
4.2.4 の挙動もおかしい気はする。
>それ以外の場合(オーバーロードの解決)は純粋に出現
>順序で決定されると。
先に宣言されたものが常に選ばれるみたいに読めて微妙。
>150
13.3.3.2/2
152:135
09/03/21 02:32:23
>151
> 「NS2->NS1の書き換え」ってどこ書き換えたの?
135のサンプルを「NS1->NS2の書き換え」の間違えです。
まとめると
//1を有効 & 他無効 => 2
//2を有効 & 他無効 => 1
//3を有効 & 他無効 => 2
#include <stdio.h>
namespace NS1 { struct HUGA {}; }
namespace NS2 {
int get(void*) { return 1; }
// int get(NS1::HUGA * ) { return 2; } //1
template <typename T>
int f() {
NS1::HUGA huga;
return get(&huga);
}
int get(NS1::HUGA * ) { return 2; } //2
}
namespace NS1 {
// int get(NS1::HUGA * ) { return 2; } //3
}
int main() { return NS2::f<int>(); }
153:135
09/03/21 02:42:13
補足
152のサンプルは3.3.6では全部2になります。
4.2.4みたいにADLの対象か否かで解決遅延対処になるか
否かってのはなんかしっくりこない・・・。
154:127
09/03/21 05:46:58
>>128
でたらめな比較結果を返す関数を与えた場合の動作は未定義なんですね。
致し方ないので既知の問題としてドキュメントに記載してユーザに注意
してもらうことにします。ありがとうございました。
155:デフォルトの名無しさん
09/03/21 08:00:42
比較関数全体をユーザ定義にするんじゃなくて、比較処理はC++で書いて、
条件を(比較結果がデタラメにならない程度に)カスタマイズできるように
すればいい気がするなぁ。
156:デフォルトの名無しさん
09/03/21 13:19:32
for_eachについて教えてほしいのですが、下記のコードでfor_eachの三番目の引数である
CPrint()に引数を設定ていないのにveciTableの要素が、void operator()(int iValue) 〜へ渡されているのはどうしてですか?
#include <vector>
#include <algorithm>
#include <cstdio>
using namespace std;
struct CPrint {
void operator()(int iValue) { printf("%d\n", iValue); }
};
int main() {
vector<int> veciTable(3);
veciTable[0] = 111;
veciTable[1] = 222;
veciTable[2] = 333;
for_each(veciTable.begin(), veciTable.end(), CPrint());
return 0;
}
157:デフォルトの名無しさん
09/03/21 13:22:22
>>156
CPrint()(veciTable[0]) などのように operator () が呼び出されるから。
158:デフォルトの名無しさん
09/03/21 13:22:33
std::tr1::bindですが、↓がコンパイルできません。
Aのメンバ関数に引数を渡したいのではなくて、X::funcBにAを渡したいのです。
どうすればいいでしょうか。
class X {
class A { ... };
void funcA(void) { for_each(container.begin(), container.end(), std::tr1::bind(&X::funcB, _1)); }
void funcB(const A& a) { ... }
std::vector<A> container;
};
159:デフォルトの名無しさん
09/03/21 13:24:23
>>158
エラーメッセージは?
160:デフォルトの名無しさん
09/03/21 13:26:23
>>158
X のインスタンス指定が抜けてるよ。
std::tr1::bind(&X::funcB, this, _1) でいけるんじゃない?
161:158
09/03/21 13:46:42
>>160 であっさりうまくいきました!
昨日一晩の苦労が…。感激です。
>>159
thisがないときのエラーメッセージは(VC9ですが)
「error C2825: '_Fty': '::' が後に続くときは、クラスまたは名前空間でなければなりません」の後
「テンプレートのインスタンス化 'std::tr1::_Result_type1...' の参照を確認してください」という
bind特有の長いメッセージが続きます。
162:デフォルトの名無しさん
09/03/21 14:21:43
長文で申し訳ない。
>153
やっぱり 4.2.4 の挙動もおかしいと思う。
インスタンス化時点での名前解決の対象になるのは ADL のみみたいだけど、
そもそも、テンプレートパラメータに依存する dependent name に対するものだけなので。
ぴったりしたケースじゃないけど 4.3.1 に対してこんなバグレポもあがってるので、
gcc の挙動をそんなに信用できないと思う。
URLリンク(gcc.gnu.org)
テンプレートパラメータに依存しないものならインスタンス化を待たなくとも結果は変わらない
はずだし、遅延すると通常の名前に対するものと異なる直感に反する結果を与えかねないので、
定義時点で名前解決を行えばいい。
一方、テンプレートパラメータに依存する名前について定義時点のみで名前解決を行うとすると、
制約が強すぎる。例えば STL を使う場合、コンテナのヘッダをインクルードする前にコンテナの要素型と
必要な操作が宣言されていなければならない。
従って、インスタンス化まで名前の解決を遅延したいが何でもかんでも名前解決の対象にすると、
これまた直感に反する結果を与えかねない。
ということで、ADL のみに制限しているという理解。
……なんだが、14.6.4 の規定自体に問題がある気がしてきた。
ADL じゃない lookup はインスタンス化時点では行わないようにも読めるんだが、qualified name lookup も
インスタンス化時点で行われないと、dependent name な基本クラスのメンバにアクセスできなくなるので
そんなわけないと思うのだが。
C++ Templates The Complete Guide では dependent qualified name もインスタンス化時点で名前解決されるって
書いてあるんだが、一方、インスタンス化時点で名前解決されるのは ADL のみという記述も結構見かける。
163:デフォルトの名無しさん
09/03/21 14:27:34
g++の挙動はおかしいから
有名なソフトじゃ禁止コーディング規約いっぱいあるよ
C++のインプリで世界最悪なのがg++だし
164:デフォルトの名無しさん
09/03/21 20:10:57
アンチg++必死だなw
165:135
09/03/21 20:28:38
>162
つまみ食いみたいなレスになりますが・・・
>gcc の挙動をそんなに信用できないと思う。
私もgccのbugzilla幾つか確認したけどアサインされてないバグって
結構いっぱいありますな。外野があれこれいうのもなんだけどあれで
C++0x対応が収束するのやら。
> ということで、ADL のみに制限しているという理解。
そもそもオーバーロードは遅延名前解決の対象になるのか?
152の//3はnamespaceが違うのでget(void*)とはオーバーロードの
関係ではないわけで、そういう風に考えると、名前解決が遅延するのも
自然な気がしてきました(w
f()内でget呼び出しがTに依存していないのにも関わらず
名前解決が遅延するのがバグであったとしても、
本来はTに依存させて使用するのが普通で、そのバグを
前提にしたロジックを組まなければ何とかなるかと。
166:デフォルトの名無しさん
09/03/21 21:19:05
>165
> そもそもオーバーロードは遅延名前解決の対象になるのか?
> 152の//3はnamespaceが違うのでget(void*)とはオーバーロードの
> 関係ではないわけで、そういう風に考えると、名前解決が遅延するのも
> 自然な気がしてきました(w
名前解決(というより照合と呼ぶべきかもしれないが)とオーバーロードの解決は別のステップで、
まず名前の解決を行い、その後、名前解決によって発見された候補関数群から、呼び出すべき関数が
選び出される(これがオーバーロードの解決)。
なので、名前の解決が遅延された時点でオーバーロードの解決も遅延される。
ちなみに、private とかのアクセス制限が確認されるのはこの後。
167:デフォルトの名無しさん
09/03/22 01:01:10
>>163
>C++のインプリで世界最悪なのがg++だし
いるいる、「絶対○○」とか「世界一○○」とか何の根拠もなしに比較したかのように語る人w
168:デフォルトの名無しさん
09/03/22 01:28:11
ここの住人は頭がみんな良さそう
名前空間なんて、
松坂大輔
宮川大輔
のようなものとしか理解してないんだがな、俺的には。
169:デフォルトの名無しさん
09/03/22 02:52:53
よくわからんけど、gccは新しいのでやってくれ。windowsもlinuxも4.3.3以前のは入れてない。
170:デフォルトの名無しさん
09/03/22 13:12:11
gccについて疑問に感じたのなら、本家のforumが待ってるよ。
171:デフォルトの名無しさん
09/03/22 16:44:02
>>169
gccの4.x系は、Linux上での動作はいいが、Windows上での動作は問題があるって聞いてるんだが。
だからMinGWも最新安定版はg++は3.4.5なんだと。
(アルファ版なら4.x系もあるだろうが。)
172:デフォルトの名無しさん
09/03/22 16:46:44
gcc の話は↓こちらでどうぞ。
GCCについて part8
スレリンク(tech板)
173:デフォルトの名無しさん
09/03/23 12:22:42
聞いた話じゃなぁ
174:デフォルトの名無しさん
09/03/23 23:18:14
心を振るわせる話なら信用するのに
どうして鼓膜を振るわせる話は信用しようとしないのだ。
175:デフォルトの名無しさん
09/03/24 00:30:19
質問です
ソースファイルAでnewしたインスタンスを
別のソースファイルBでdeleteしたりしても大丈夫なんですか?
176:デフォルトの名無しさん
09/03/24 00:39:08
インスタンスの実体が対応してれば大丈夫だろ
177:デフォルトの名無しさん
09/03/24 01:03:40
変な設計だとは思うけどな
178:デフォルトの名無しさん
09/03/24 02:43:52
コンストラクタをcppに書いて、デストラクタをインラインでヘッダに書けば普通に起こる状況だな
179:デフォルトの名無しさん
09/03/24 08:21:36
クロスDLL問題ってのとは全くの別物だよね?
そもそもどうしてあれはダメなんだろ?
180:デフォルトの名無しさん
09/03/24 09:21:41
それは、それぞれでnewとdeleteの実装が別物だとうまくいかないという話。
msvcr90.dllですべて統一するとか、shared_ptrのようにdeleteごと渡すとかすればいい。
そして、コンパイラが違うとvtblやRTTIの形式が違うという話へ続く……。
181:デフォルトの名無しさん
09/03/24 09:28:56
そんな面倒事に悩まされる前に一つのモジュールに閉じ込める工夫に労力注げ…と
182:179
09/03/24 09:35:57
>>180-181
へーそういうことか。
ありがとう!
183:デフォルトの名無しさん
09/03/24 22:12:11
テンプレートの規則や仕様に
詳しくなれる本ってありますかね?
184:デフォルトの名無しさん
09/03/24 22:25:18
>>183
ない
185:デフォルトの名無しさん
09/03/24 22:26:32
>>184
嘘つくな洋書で一冊出てるだろ
教えろよ
186:デフォルトの名無しさん
09/03/24 22:27:32
>>185
詳しくなれるかどうかは別。
詳しく書いてるかもしれないけど。
187:デフォルトの名無しさん
09/03/24 22:29:14
c++ templatesとか
c++ template metaprogramming とか
188:デフォルトの名無しさん
09/03/24 22:30:10
URLリンク(books.google.com)
189:デフォルトの名無しさん
09/03/25 01:24:12
C++編(標準ライブラリ) 第27章 例外クラス
URLリンク(www.geocities.jp)
ここで紹介されている
std::overflow_error
std::underflow_error
が起こる例は、例えばどんなのがあるの?
前者はともかく後者がわからん。。。
190:デフォルトの名無しさん
09/03/25 03:14:14
標準じゃunderflow_error投げる規定は無さそうだな。 >189
191:189
09/03/25 09:38:25
>>190
そうなのか。
とりあえず作っちゃった謎の例外か?
どうも。
192:デフォルトの名無しさん
09/03/25 11:17:10
std::underflow_error - Google Code Search
URLリンク(www.google.com)
193:デフォルトの名無しさん
09/03/25 22:41:38
0をboolに変換するとfalse, 0でない数をboolに変換するとtrueになるんだよね?
これは分かる。
では
falseをintに変換すると0, trueをintに変換すると1
ってのは仕様上正しい?
特に後者が心配でならないんだが、標準で1になることが保証されている?
194:デフォルトの名無しさん
09/03/25 22:47:03
>>193
> 4.5 汎整数昇格
> 4 bool 型の右辺値は,int型の右辺値に変換することができる。falseは,0になり,trueは,1になる。
195:デフォルトの名無しさん
09/03/25 23:15:06
でも、int値をtrueと比較するのは危険なんだよね。
196:デフォルトの名無しさん
09/03/25 23:18:49
別に気にするな
引き継いで逃げ切ればOK
197:デフォルトの名無しさん
09/03/25 23:30:32
if ( int値を返す式 ) { }
は正常に動作するけど
if ( int値を返す式 == true ) {}
とやると意図したとおりに動かない可能性がでてくる
妙なルール。
198:デフォルトの名無しさん
09/03/26 17:19:01
>if ( int値を返す式 == true ) {}
は if ( int値を返す式 == 1 ) {} と同じ動作?
199:デフォルトの名無しさん
09/03/26 18:56:19
うん。
200:デフォルトの名無しさん
09/03/26 21:25:19
左辺をboolに変換して比較すれば問題ないのにな
変なルールだよな仕方ないけど
201:デフォルトの名無しさん
09/03/26 21:26:34
201
202:デフォルトの名無しさん
09/03/27 01:14:18
>>197
C が 0 以外は true と決めてたわけで better C としての
C++ は、従うしかなかったんちゃう?
まぁ、そんな言語は山ほどあるわけだが………
203:デフォルトの名無しさん
09/03/27 10:41:29
比較とか論理演算とかが結果を0と1で返すから
trueをそっちに合わせたんじゃね?
204:デフォルトの名無しさん
09/03/27 14:23:37
#define true 1
#define false 0
typedef char bool;
昔ありそうな超手抜き実装
205:デフォルトの名無しさん
09/03/27 14:24:25
手抜き?
206:デフォルトの名無しさん
09/03/27 14:30:14
Exceptional C++を読むとboolの必要性が説かれている
207:デフォルトの名無しさん
09/03/27 14:44:47
int値をbool値に変換するのは情報の欠落が生じるけど、その逆は生じない。
だからint型とbool型を比較すると、暗黙の型変換のルールに従って、bool型の方がint型に昇格する。
結果、>>198のようになって、意図したとおりに動かなくなる。仕様どおり!・3・
208:デフォルトの名無しさん
09/03/27 21:09:51
C++の副作用に関して良く解らないので教えてください。
int a=0;
int b=0;
int func(int c){ b=a; return c; }
このとき、
func(++a);
を通ると、bに1が入ることは保障されますよね?
func(a++);
この場合はどうでしょうか?
bに0が入る?
bに1が入る?
鼻から悪魔?
209:デフォルトの名無しさん
09/03/27 21:16:01
>>208
関数を呼ぶ直前と、関数から戻った直後に副作用完了点がある。
だから、どちらもbは1になる。
210:デフォルトの名無しさん
09/03/27 21:22:54
>>209
有難うございます。
211:デフォルトの名無しさん
09/03/27 21:28:25
>209
すいません。もうひとつ教えてください。
&& || ?: , 以外の演算子は副作用完了点ではないんですよね?
自分でオーバーロードした演算子の場合は
通常の関数と同じように関数に入る直前と戻った直後に副作用完了点はありますか?
212:デフォルトの名無しさん
09/03/27 21:32:31
>>211
ある。
ただし、最初にあげてる演算子をオーバーロードした場合、
組み込み演算子と違って、オペランドの評価順序が不定になったり、
ショートサーキットでなくなったりするのには注意。
213:デフォルトの名無しさん
09/03/27 21:42:28
有難うございます。
たびたびすみません。
「オペランドの評価順序が不定になる」とは何ですか?
組み込み演算子でも一般的に不定だと思うのですが、
オーバーロードによって不定でなかったものが不定になる場合があるのですか?
214:デフォルトの名無しさん
09/03/27 21:53:18
あ、
組み込みの && || ?: , 演算子の評価順序のことですね?
自己解決しました。
215:デフォルトの名無しさん
09/03/27 22:22:27
printfで64bit値(u_int64_t)を表示したい。
32bit環境では %llu
64bit環境では %lu
両対応でスマートな解決法ってないものだろうか?
define拾ってきて切り替えるくらいしか思いつかない
216:デフォルトの名無しさん
09/03/27 23:32:40
unsigned long long にキャストしていつでも %llu で表示する
217:デフォルトの名無しさん
09/03/27 23:35:15
VCとかは%I64uだったような
defineで切り替えるしかないんじゃね?
218:デフォルトの名無しさん
09/03/28 00:21:24
末尾にLがついてるのってlong int だよな?
219:デフォルトの名無しさん
09/03/28 00:25:57
>>216
その手があったか!
思考がループしてそこまで考え付かなかった。 thx
220:デフォルトの名無しさん
09/03/28 01:23:02
C99かC++0xでは<inttypes.h>のPRIu64を使う
221:デフォルトの名無しさん
09/03/28 19:28:24
>>220
それだと、uint64_t使えというところから始めないと。
222:193
09/03/28 19:54:02
>>194
あまりにもな遅レスすまんかった!!
ちょっと私用が。。。
汎整数昇格 了解しました。
ありがとう。
223:デフォルトの名無しさん
09/03/28 23:31:56
最近C++の勉強をはじめた者なんですが、n個のデータを打ち込んで
それらの平均値や標準偏差を求めるプログラムを打ち込んだところ、
.\例題2.1.cpp(10) : error C2679: 二項演算子 '>>' : 型 'const char [2]' の
右オペランドを扱う演算子が見つかりません (または変換できません)。
というエラーが出てしまったんですが、なにが原因かさっぱりわかりません。
いつもと同じように打ち込んだつもりなのですが、原因分かる方いませんか?
224:デフォルトの名無しさん
09/03/28 23:33:21
せめて例題2.1.cppの10行目くらい見せろよ
225:デフォルトの名無しさん
09/03/28 23:43:10
cout<<"nの値は?"; cin>>n>>"\n";
こうなっています。見たところどこにもミスはないと思うのですが・・・
226:デフォルトの名無しさん
09/03/28 23:45:32
>>225 cout<<"nの値は?"; cin>>n;
227:デフォルトの名無しさん
09/03/28 23:47:54
>>225
場合によって意味が変わるけど<<は出力、>>は入力
cin >>n
nに入力された値を入力
n>>"\n";
次に入力された値を"\n"に入力
だぞ?
おかしいだろ
228:デフォルトの名無しさん
09/03/28 23:50:52
>>226
ああ、なるほど!入力と出力の指令が混同してましたね(汗)
こりゃ動かんわ・・・どうもありがとうございました!!
229:デフォルトの名無しさん
09/03/29 00:00:58
以下のようなコードを見たのですが、
これってC++のルール上、
((T*)NULL)->function() は安全にコールできるんでしょうか?
class T {
void function(){
if (this == NULL){
return;
}
メンバにアクセス
}
}
function() が virtual だとしたらヌルポ例外ですよね?
230:デフォルトの名無しさん
09/03/29 00:06:01
>>299
C++にnull_pointer_exceptionなんて気の利いたもんはない。多分OSがそのプロセスを殺そうとするだけだろう。
経験則ではメンバに触れなければ落ちないけど規格で決まってる訳ではないだろうからお勧めしない。
231:デフォルトの名無しさん
09/03/29 00:07:05
誰もいないところにパスした。
>>230は>>229宛
232:デフォルトの名無しさん
09/03/29 00:13:00
>>229
((T*)NULL)-> が現れた時点で未定義動作になる。関数の中身は関係ない。
233:デフォルトの名無しさん
09/03/29 00:20:21
>>230 >>232
ありがとうございます。
234:デフォルトの名無しさん
09/03/29 00:41:21
((T*)NULL)->function()
このfunction()をstatic関数にしてみるとどうだろう?
有識者のご意見を聞きたい。
class T
{
public:
static void function(){}
};
int main()
{
((T*)NULL)->function();
return 0;
}
235:デフォルトの名無しさん
09/03/29 00:43:43
未定義。だいたいコンパイル通るのか
236:デフォルトの名無しさん
09/03/29 00:46:42
通るよ
237:234
09/03/29 00:49:17
ちゃんと質問する前にコンパイル済み。
通ったよ。g++ね。
C++では
(T*)NULL
自体は未定義じゃないよね?
>>232さんが言っているように
>((T*)NULL)-> が現れた時点で未定義動作になる。関数の中身は関係ない。
なのだとしたらstaticだろうが何だろうが確かに未定義になるのだろう。
が、static関数なら実質的にグローバル関数扱いなのではと思っているので疑問だった。
staticなメンバ関数はstaticなメンバ変数にしか触れることができないじゃん。
>>236
チェックしてくれてありがとう。
238:デフォルトの名無しさん
09/03/29 00:54:50
c++でcキャストは使うべきじゃないよ。 >229
239:デフォルトの名無しさん
09/03/29 00:55:55
今更そこに突っ込む不毛さ。
240:デフォルトの名無しさん
09/03/29 01:01:01
class Test
{
public:
void func( void ){ std::cout << "test"; }
};
int main( void )
{
static_cast<Test*>(NULL)->func();
return 0;
}
メンバ変数に触れなければこれもコンパイル通って動きそうだけど
さすがに未定義か?
241:デフォルトの名無しさん
09/03/29 01:04:39
>>240
括弧が足りなくないか?
242:デフォルトの名無しさん
09/03/29 01:06:19
ほぼ全ての環境で動くだろうけど未定義。
メンバ関数の呼び出しはつまるところ暗黙の引数thisを含む関数の呼び出しにすぎない。それがNULLであったとしても関数を実行するコードはあるので実行はされる。
でも未定義。
243:237
09/03/29 01:07:21
>>240
メンバ関数に触れていても通るよ。
コンパイラにはNULLかどうかなんてコンパイル時に分からない。
全く問題無く通り、実行時に鼻から悪魔が出て来ることとなる。
244:デフォルトの名無しさん
09/03/29 01:09:10
ところが
>>237
が言っているstatic関数になると話は別じゃね?
俺はstatic関数に詳しいとかいうわけじゃないから知らんけど、
グローバル関数に無理矢理クラス内というスコープつけたものという認識。
245:デフォルトの名無しさん
09/03/29 01:21:49
>>244
未定義動作になるのは、オブジェクトを指していない参照に対して単項 & や sizeof など特殊な
ものを除く演算子を適用した場合はいつでも。
アロー演算子 -> の右にあるのが何だとか関数が static だとかそんなのは関係ない。
246:244
09/03/29 01:27:35
>>245
へーそうなんだ、ありがと。
247:237
09/03/29 01:33:32
delete NULL;
ってのがあったな。めずらしく安全な例で。
248:デフォルトの名無しさん
09/03/29 01:41:17
>245
ポインタだからいいんじゃね?
4.10 Pointer conversions
(snip)
A null pointer constant can be converted to a pointer type;
the result is the null pointer value of that type and is distinguishable
from every other value of pointer to object or pointer to function type.
249:デフォルトの名無しさん
09/03/29 01:43:30
>>248
p->x は (*p).x と定義されている。
250:デフォルトの名無しさん
09/03/29 01:47:04
キャスト演算子だけなら問題ないってことだろ。
((T*)NULL);
251:デフォルトの名無しさん
09/03/29 02:09:54
std::vector<ポインタ型> v;
というのがあって
あるタイミングで
v.push_back(アドレス);
これやるとmemoty.stlの__rw_basis::data()で落ちるんです。どうやらタイミングとかが関係するみたいなんで
どなたかエスパーお願いできないでしょうか?再現ができなくて申し訳ないんですが・・・
252:デフォルトの名無しさん
09/03/29 02:13:33
>>251
スレ違いです。↓へどうぞ。
スレリンク(tech板)
253:デフォルトの名無しさん
09/03/29 02:16:08
環境書いてよ。それだけだとRogueWave製の標準ライブラリを使ってることぐらいしか分からない。
254:デフォルトの名無しさん
09/03/29 02:16:48
>>250
それはあたりまえ。だれもそんなところ問題にしていない。
255:デフォルトの名無しさん
09/03/29 10:59:55
__LINE__みたいに関数名表示するマクロありませんか?
256:デフォルトの名無しさん
09/03/29 11:02:31
標準ではC99で__func__。
コンパイラ拡張なら色々。
257:デフォルトの名無しさん
09/03/29 11:34:03
ちなみにマクロじゃないぜ。
258:デフォルトの名無しさん
09/03/29 17:40:26
戻り値が指定されてる関数で、
関数の最後にreturnが無くても
関数の最後まで到達しないなら
C++の規格上は正しくコンパイル、実行できることは保障されますか?
たとえば以下のような記述は問題ないですか?
int a(int n){
if (n){
return 0;
}
else {
return 1;
}
}
int b(int n){
if (n*n>=0){
return 0;
}
}
int c(int n){
while(1);
}
259:デフォルトの名無しさん
09/03/29 17:45:52
全部問題あります。
260:デフォルトの名無しさん
09/03/29 17:48:43
>>258
b()とc()は警告出るだろ
261:デフォルトの名無しさん
09/03/29 18:46:39
>>258
戻り値が指定されてる関数で、
関数の最後にreturnが無くても
関数の最後まで到達しないなら
C++の規格上は正しくコンパイル、実行できることは保障される。
ただ、b() はその条件を満たしていない。
262:デフォルトの名無しさん
09/03/29 19:44:12
nの値により条件を満たすのでは?
263:デフォルトの名無しさん
09/03/29 19:49:06
値によらないだろw
264:デフォルトの名無しさん
09/03/29 19:56:38
仮に
int b(int n){
if (n*n>=0){
return 0;
}
assert(false);
return 1;
}
と書いても鼻から悪魔が出るだけだな
# スレ違いっぽいが
265:デフォルトの名無しさん
09/03/29 21:15:29
俺は、例えばn=1000000って意味に取った
266:デフォルトの名無しさん
09/03/29 21:26:00
ああ二乗してるから必ず正なわけか
267:デフォルトの名無しさん
09/03/29 21:27:06
でもオーバーフローした時に悪魔だな
268:デフォルトの名無しさん
09/03/29 22:07:55
aもbもcも書いたとおりにコンパイルも動作もできるし
と思っているのだが,bはNGなのか?
269:デフォルトの名無しさん
09/03/29 22:12:18
bを実行したとき、nの二乗がintをoverflowしたときは鼻から悪魔が出る
それ以外はコンパイルも動作もOK
270:デフォルトの名無しさん
09/03/30 11:04:54
int b(int32_t n) {if (int64_t(n) * n >= 0) return 0;}
なら大丈夫かな?
271:デフォルトの名無しさん
09/03/30 12:38:17
大丈夫も大丈夫じゃないも、問題が起きそうな記述に警告を出してくれない方がよほど大丈夫じゃない
272:デフォルトの名無しさん
09/03/30 12:50:14
本当に簡単に鼻から悪魔るんだな
もうsqrt(abs(n)) <= INT_MAXとかoptionalとか使って部分関数として定義するしかないのか
273:デフォルトの名無しさん
09/03/30 20:07:59
コンマ演算子は副作用完了点で、
関数の引数のコンマは副作用完了点ではないのは理解してますが、
初期化子のコンマは副作用完了点でしょうか?
たとえば、以下のコードは正しく動きますか?
struct T {
int a,b;
......
};
int f();
void g(){
T t={ f(), t.a };
.......
}
void h(){
int a[2] = { f(), a[0] };
.......
}
274:デフォルトの名無しさん
09/03/30 20:27:52
あと、同じ型で複数の変数を定義する時のコンマは副作用完了点でしょうか?
たとえば、以下のコードは正しく動きますか?
void g(){
int a=f(),b=a;
......
}
275:デフォルトの名無しさん
09/03/30 22:21:29
継承した親クラスの実体を参照するメンバ変数を、なるべく無駄なメモリを消費せずに
実現したいのですが、よい方法はないでしょうか?
メンバ関数を使えばよいのは承知しているのですが、できれば "()" を書かずに済ませたいのです
struct coord { int x; int y; } ///< これを親にしたい
class state {
coord position; ///< この部分をメンバ変数として持つのではなく親から継承したい
coord velocity;
void foo();
}
extern void bar(coord& param);
void state::foo() { bar(position); bar(velocity); }
現在は親の参照を返すメソッドを作り、マクロでごまかして無理矢理実現しています
しかしマクロがソース全域に作用してしまうのでなんとかしたいのです
class state: public coord {
coord velocity;
coord& position() { return *this; } ///< 参照を追加
const coord& position() const { return *this; } ///< const 参照を追加
#define position position() ///< 強引にマクロ…関係ない部分まで作用してしまうのが難点
void foo(); ///< foo() 内で親の実体を *this ではなく position と書いてアクセスしたい!
}
試しにこんな風に書いてみたのですが、うまくいきませんでした
class state: public coord {
coord velocity;
const coord& position; /// こんな感じの参照をメモリ消費なしで定義したい
state(): position(*this) {} /// ここでエラー orz
void foo();
}
276:デフォルトの名無しさん
09/03/30 23:02:24
>>275
何かいろいろとアレな気がするが、少なくとも私の環境では
struct coord { int x; int y; };
class state: public coord {
coord velocity;
const coord& position;
state(): position(*this) {}
void foo();
};
というコードはコンパイルが通る。
エラーが出るというなら、コンパイラの名前とエラーメッセージを書いてほしい。
あと、クラス定義の最後のセミコロンを忘れていないかね?
277:デフォルトの名無しさん
09/03/30 23:11:06
セミコロンを忘れてしまい申し訳ないです。
コンパイラはVC++6.0 SP5+プロセッサパックでエラーメッセージは以下の通りです
error C2758: 'position' : オブジェクト コンストラクタの初期化リストで初期化されませんでした。
'position' の宣言を確認してください。
最近のコンパイラではこのソースでも動くとのことなので、こちらでもコンパイラを変えて
試してみようと思います。
278:デフォルトの名無しさん
09/03/30 23:12:07
>>275
なんか、やりたい動機がよくわからんのだが・・・。
stateからxは、継承関係にあるから当然そのまま参照できるよね。
void foo() { x = 1; }
親クラスのメンバであることが明示されたコードを書きたいってこと?
それなら
void foo() { coord::x = 1; }
これでいいと思うんだけど。
279:デフォルトの名無しさん
09/03/30 23:13:40
何度も書き込んで申し訳ありません、VC6でもコンパイルできました
warning C4355: 'this' : ベース メンバ初期化リストで使用されました。
エラーではなくワーニングが出ていたのが原因でした。お騒がせしました
280:デフォルトの名無しさん
09/03/30 23:15:01
>>278
foo()内部で bar(*this); ではなく bar(position) と書きたい、というのが動機です
281:デフォルトの名無しさん
09/03/30 23:25:21
>>280
あー、何となく気持ちはわかる。でも俺がやるとしたら
#define This (*this)
的な方法を選ぶかなぁ、実際にはやらないだろうけどww
282:デフォルトの名無しさん
09/03/31 00:17:31
ありがとうございます。説明不足で申し訳ないです。動機はもっと正確に書くと、
クラス同士が親子関係を持っていなかった時点と同じ可読性(できれば完全に同一の記述)を
クラス間に親子関係を持たせた後も維持したい、です
1. foo() 内部で bar((coord&)*this) や bar(position()) と書かずに以前のまま bar(position) と書きたい
2. foo()の外部で
state a;
coord b;
a = b;
a.position = b;
上記のように書いた場合に両者のコンストラクタを区別したい
区別のために ((coord&)a) = b と書きたくない
3. 親を参照するメンバ変数 position& が最適化後に実体を持たずに消えてほしい (調べてみたところ、VC6では消えませんでした)
マクロを使うことで制限つきながら上記3つは実現できたのですが
マクロの範囲が広すぎて関係ない部分まで影響が出るのが難点でした
要はほとんど好みの問題なのですが、どんな泥臭い方法でもいいので、
A. 無駄なメモリを消費しない自分自身(親の実体)への参照を定義するか、
B. プリプロセッサに頼らずにメンバ変数の記述でメンバ関数の呼び出しが行われるようにしたいのです
もしBが可能なのであれば、例えばコンストラクタがあってunion化できないメンバ変数へ
部分的なアクセスを行う擬似unionのようなことも(C++の理念的にどうなのかは別として)できそうです
283:デフォルトの名無しさん
09/03/31 00:20:18
マクロは全力で避けろ
継承は is a の関係
包含の方が多くの場合適切
なぜ男なんだ
284:デフォルトの名無しさん
09/03/31 00:41:45
>>282
なんか、説明聞いたらさらにツッコミたくなってしまったw
foo() の汎用性を持たせたいなら static foo(coord&) にして
メンバの場合
foo(*this);
変数の場合
coord c;
foo(c);
と俺はしたくなる。
ちなみに、bar((coord&)*this) は冗長なキャストだけど、わざとそう書いたんだよね・・・?
285:デフォルトの名無しさん
09/03/31 02:45:50
すみませんが、
>>273 >>274 お願いします。
286:デフォルトの名無しさん
09/03/31 02:58:04
>>285
少なくともVC++8で試してみたらコンパイルは通って動作も期待通りだった。
C++の言語仕様として保証されているものかどうかは知らん。
287:デフォルトの名無しさん
09/03/31 03:44:39
>>273
挙げられた例では未初期化のオブジェクトを参照しているので、
副作用完了点に関わらず、値が不定となる。つまり int i = i; と同じ。
ちなみに、初期化子および初期化宣言を区切るカンマではそれぞれで
「完全式」が区切られるので、副作用完了点となる。
ただし並べられたそれらの順番について C++ 2003 では規格に記述がなかったので、
次期改定で記述順に評価されることが決まる予定。
URLリンク(www.open-std.org)
なお、同じく次期改定で追加される initializer list については、・・・アレ、
評価順についての記述が見当たらない。大丈夫なんだろうか?
288:デフォルトの名無しさん
09/03/31 06:18:52
C++かCでデータ構造関係のアルゴリズムが詳細に
掲載されている本というとどんなのがありますかね?
289:デフォルトの名無しさん
09/03/31 21:09:06
>>287
ありがとうございます。
リンク先は非常に参考になりました。
すみませんが、依然 >>274 がわかりません。
おわかりでないでしょうか?
> 挙げられた例では未初期化のオブジェクトを参照しているので、
これに >>274 も含まれていたりしますか?
英語版wikipediaでは、
> At the end of an initializer; for example, after the evaluation of 5 in the declaration int a = 5;.
とありますが、
an initializer がどういう単位か分かりません。
MSDNでは、
> The end of a full initialization expression, such as the end of an initialization in a declaration statement.
とありますが、a full initialization expression が、
int a=5, b=a*10, *c=&a, &d=a;
のa,b,c,d それぞれなのか、この文全体なのかわかりません。
よろしくお願いします。
290:デフォルトの名無しさん
09/03/31 21:32:20
std::stack<std::string> s;
とした場合、
s.push(〜)はsの中に〜のコピーが出来る仕様でしょうか?
つまり
std::stack<std::string> s;
std::string *p=new std::string;
s.push(*p);
delete p;
としたとしても、スタックsは何の影響もなくs.top()とかしていいんでしょうか?
291:デフォルトの名無しさん
09/03/31 21:44:03
多分だめじゃよ、とーまんこー。
コンテナは値セマンティクスを要求するから
値として振舞わないものは入れられないのじゃ。
入れるならしぇあぽを入れなされ。
そして、そのプログラムは「依頼人のいない弁護士」を
保持することになる。
292:デフォルトの名無しさん
09/03/31 21:46:58
>>290
stackにpushした時点でstringがstack内にコピーされるから問題ない。
293:191
09/03/31 21:57:27
あぁ、ほんとだpushの引数に * が付いてた^^
すまんこ学園。つまり>>292が正解。
294:290
09/03/31 22:19:18
>>291-293
なるほど。
ありがとうございました。
これで安心して組めます。
295:デフォルトの名無しさん
09/03/31 22:30:08
すまんこ・・・
296:デフォルトの名無しさん
09/03/31 23:45:05
トライ木ってどんな木なのでしょうか?
データ構造がいまいちわかりません
297:デフォルトの名無しさん
09/04/01 00:09:25
>>296↓
Wikipedia項目リンク
298:デフォルトの名無しさん
09/04/01 00:12:16
たとえばABC,ADE,ABDの三要素のトライ木を書くとこんなかんじ
A-B-C
| |-D
|
|-D-E
左端のAが木のトップで右側が子要素な。
親から末端ノードまでの要素を連結すると登録した要素になる。
ツリーの深さはキー長に比例するけど1回辺りの比較が超軽いのが特徴。
これを改良したのにパトリシア木とかあるけど詳細は略
次ページ最新レス表示スレッドの検索類似スレ一覧話題のニュースおまかせリスト▼オプションを表示暇つぶし2ch
5029日前に更新/185 KB
担当:undef