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

【初心者歓迎】C/C++室 Ver.63【環境依存OK】

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2009/01/09(金) 20:07:31
エスケープシーケンスやWin32APIなどの環境依存なものでもOK。
ただしその場合、質問者は必ず環境を書きましょう。
※sage禁止です(と代々スレに書いてありますが自己判断で)。

【前スレ】
【初心者歓迎】C/C++室 Ver.62【環境依存OK】
http://pc11.2ch.net/test/read.cgi/tech/1229095398/l50

【アップローダー】(質問が長い時はココ使うと便利)
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm

◆ソースのインデントについて
半角やTABでのインデントはスレに貼ると無くなります。
そのため、アップローダーに上げるのが最も良いですが、
直接貼るのであれば、全角空白か に置換しておくことをお勧めします。
0153デフォルトの名無しさん2009/01/14(水) 22:38:50
>>152
自分用のチラシの裏.スレ汚しスマソ

(*p)() // *p は関数型 void (char*)
p() // p は関数ポインタ型 void (*)(char*)

(*(void (*)(char*))0x80483d4)() は関数型へのキャスト?
((void (*)(char*))0x80483d4)() は関数ポインタ型へのキャスト
0154デフォルトの名無しさん2009/01/14(水) 22:39:43
>>150 によると *p も関数ポインタ型のようだが。
0155デフォルトの名無しさん2009/01/14(水) 22:41:44
C++ でチェックしてみた。

#include <iostream>
#include <typeinfo>

void foo() { }
void (*p)();

int main() {
std::cout << typeid(foo).name() << std::endl;
std::cout << typeid(p).name() << std::endl;
std::cout << typeid(*p).name() << std::endl;
}

出力
FvvE
PFvvE
FvvE

*p はやっぱり関数型じゃねえか。
0156デフォルトの名無しさん2009/01/14(水) 22:42:30
****p();
を試したらわかるんでないか
0157デフォルトの名無しさん2009/01/14(水) 22:43:27
関数型の値に * をつけると、
一旦関数ポインタ型に変換されてから
また * が作用して関数型に戻るんでないかい?
0158デフォルトの名無しさん2009/01/14(水) 23:11:45
以下の4つは全部同じ

printf("%p\n", func);
printf("%p\n", &func);
printf("%p\n", p);
printf("%p\n", *******p);

うろ覚えだけど、

関数型は値を評価すると自動的にアドレス(関数ポインタ型)に変換されるので、
関数ポインタ型を間接参照で関数型にしてもまた自動的にアドレスに変換される
(関数ポインタ型の間接参照は実質的に意味をなさない)

だったかな
0159デフォルトの名無しさん2009/01/14(水) 23:13:50
関数型の値は左辺値で、
右辺値に変換すると関数ポインタ型の値になる。
0160デフォルトの名無しさん2009/01/14(水) 23:28:38
>>155
C/C++の式の世界には「関数」は存在できない
生の関数が出現すると即座にその関数ポインタに変換される

だがsizeofとtypeidの中は関数が関数として存在できる数少ない例外的な場所になってる
だからtypeidすると「関数型」を見ることは出来るが、外でそれを使うことは出来ない
(ちなみにもう一つは「単項&演算子のオペランドになる時」=結局行き着く先はポインタ)
0161デフォルトの名無しさん2009/01/14(水) 23:32:37
>>160
いい加減な事を言うなよ。
関数は左辺値であるから、
左辺値を要求する所に使えば関数は関数のまま存在できるし、

typedef void hoge();
hoge& r = foo;

そもそも関数の使い方で最も代表的な関数呼び出しでは
関数が関数のまま扱われているだろう。規格的に考えて。
0162デフォルトの名無しさん2009/01/14(水) 23:39:40
>>161
そりゃ関数の参照だからだな。関数の参照は存在できるよ
hoge f = foo;みたいに関数そのものを作ろうとするとfは関数ポインタになるよ

あと関数呼び出し演算子のオペランドは関数ポインタだから
r()と呼び出せるのは関数の参照から関数のポインタに暗黙変換されるから
0163デフォルトの名無しさん2009/01/14(水) 23:41:07
>>162
規格読め。
関数呼び出し演算子のオペランドは関数あるいは関数ポインタと規定されている。
0164デフォルトの名無しさん2009/01/14(水) 23:41:48
左辺値と右辺値という言葉くらいは調べてから出直してこい。
0165デフォルトの名無しさん2009/01/14(水) 23:43:46
a.foo(); みたいなのもあるからな。
() のオペランドが関数ポインタだけとすると不都合がある。
0166デフォルトの名無しさん2009/01/15(木) 00:01:34
>>163
どこにそんなこと書いてあるんだ?

6.5.2.2 Function calls
The expression that denotes the called function shall have type pointer to function
returning void or returning an object type other than an array type.

で、注にはこう書いてる
Most often, this is the result of converting an identifier that is a function designator.

関数呼び出し演算子がさも「関数」に適用できてるかのように見えてるのは、
実際には関数から暗黙変換された関数ポインタに適用されてるんだ
0167デフォルトの名無しさん2009/01/15(木) 00:18:58
あー、C++では違うんだな
ごめん
0168デフォルトの名無しさん2009/01/15(木) 00:36:23
>>165
それって「a.foo()」で一つの構文じゃないの?
「a.foo」に関数呼び出し演算子を適用すると解釈するなら「a.foo」って何になるの
0169デフォルトの名無しさん2009/01/15(木) 07:14:41
C/C++ スレだから両者で違う点について話す時はややこしいな。
0170デフォルトの名無しさん2009/01/15(木) 18:14:35
char abc[]="ABC"; /* 文字列変数宣言 */
char *p; /* ポインタ変数宣言 */
char wk;

p = &abc[0];

と
p = abc;

は同じですか?
0171デフォルトの名無しさん2009/01/15(木) 18:45:01
同じです
0172デフォルトの名無しさん2009/01/15(木) 19:10:19
ビット演算?(16進数)がいまだによく分からないのですが
分かりやすいサイトなどご存じないでしょうか?

スレ違いでしたら申し訳ないです

(それと2月18日にC言語検定2級を受けるのですが
特に抑えておいたほうがいいポイントはありますか?)

0173デフォルトの名無しさん2009/01/15(木) 19:47:25
ビット演算がわからんというのもよくわからん
十六進数から二進数への変換はわかるよな?
その逆もわかるよな?
ANDとORとNOTの意味はわかるよな?
右シフト、左シフトもわかるよな?

全部わかってるならビット演算を全部わかってることになるから大丈夫
0174デフォルトの名無しさん2009/01/15(木) 20:14:08
16進数は2進数を4ケタまとめて1ケタで表す
それだけ
0175デフォルトの名無しさん2009/01/15(木) 20:14:32
孔子はこう言った

ならず者にはポインタを、聖なるものには列挙体を

アラベスクに幸あれ
0176デフォルトの名無しさん2009/01/15(木) 20:54:12
オブジェクト(内の変数の値)をファイルに保存・復元する
お手軽な方法ってないでしょうか?
.NetのXmlSerializerみたいな感じで。(別にXMLじゃなくても良いです)

環境はVC++2008 Expressです。
よろしくお願いいたします。
0177デフォルトの名無しさん2009/01/15(木) 20:58:18
>>176
参照だとかポインタだとか、他のオブジェクトの依存関係がどうなってるかは設計者しかしらんことだ。
一律に単純にやる方法は無いと思う。
0178デフォルトの名無しさん2009/01/15(木) 21:01:02
boost 導入してみるとか
0179デフォルトの名無しさん2009/01/15(木) 21:19:23
>>177
やっぱそうですか。自分でがりがり書くことにします。

>>178
serializationあたりでしょうか?
状況によって役に立つようでしたら使ってみます。


ともかくありがとうございます。
0180デフォルトの名無しさん2009/01/15(木) 21:44:51
ビット演算の~って

0xf003 だったら 0x0ffc ですけど

0 → f
f → 0
c → 3
3 → c

って感じでいいんですか?
0181デフォルトの名無しさん2009/01/15(木) 21:54:13
チルダは反転だな
0x0 = 0000b → 1111b = 0xF
0xC = 1100b → 0011b = 0x3

あってるけど、分からなきゃ一度2進数に変えた方がいい
0182デフォルトの名無しさん2009/01/15(木) 21:58:37
まあ4 bits 単位で見たらそういうことなんだけど、はじめは2進数に直して考えたほうがいいと思う。

都合よくCで説明されているので
http://ja.wikipedia.org/wiki/%E3%83%93%E3%83%83%E3%83%88%E6%BC%94%E7%AE%97
0183デフォルトの名無しさん2009/01/15(木) 22:00:00
>>181 182

ありおがとうございます
0184デフォルトの名無しさん2009/01/15(木) 22:03:11
>>183
> ありおがとうございます

ありおwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
0185デフォルトの名無しさん2009/01/15(木) 22:29:37
istreamから前方反復子って作れないんですか?
0186デフォルトの名無しさん2009/01/15(木) 22:48:32
istream_iterator
0187デフォルトの名無しさん2009/01/15(木) 22:51:11
<iterator> に std::istream_iterator ってのがある。
だがしかし・・・ ++ の仕様が期待通りではないかもしれない。( >> で読み出しているので)
もし期待通りのものでなかったなら、
簡単に作れるので自分で作ってみてもいいかと。
0188デフォルトの名無しさん2009/01/15(木) 22:53:54
それって入力イテレータじゃないの?
0189デフォルトの名無しさん2009/01/15(木) 22:55:09
istream_iteratorは入力反復子だろ。

<boost/spirit/iterator/file_iterator.hpp>が読み取り専用でランダムアクセスできるという触れ込み。
http://www.boost.org/doc/libs/1_37_0/libs/spirit/classic/doc/file_iterator.html
0190デフォルトの名無しさん2009/01/15(木) 22:58:05
char *st[] = { "ne", "ushi", "tora", "u", "tatu", "me", "uma", "hituji", "tori", "inu", "i" };

char *pt1, *pt2;

pt1 = *st;
pt2 = *(st + 7);

printf("%c\n", (*pt1) + 1);

出力される文字がoなのですが30分考えてもなんでか分かりません・・・

教えていただけませんか (*pt1) で nをさして + 1 で次のe だと思ったのですが・・
0191デフォルトの名無しさん2009/01/15(木) 22:59:38
>>187
つistreambuf_iterator
0192デフォルトの名無しさん2009/01/15(木) 23:01:01
アルファベット順(というか文字コードの順)に並べて、nの次の文字がoだったから。
*pt1の段階で、*を剥がしまくってもはやnという文字そのものと化している。
0193デフォルトの名無しさん2009/01/15(木) 23:01:45
>>192

そういうことだったのか!!!

ありがとうございました

かなりスッキリしましたw
0194デフォルトの名無しさん2009/01/15(木) 23:03:49
>>191
なるほど。いいものがあるんだな。
0195デフォルトの名無しさん2009/01/15(木) 23:09:46
入力反復子でアルゴリズムを適用すると、読み取った部分って捨てられてしまうよね?
普通は読み取った部分が欲しいはずなんだけど、これってどうなってるの?
0196デフォルトの名無しさん2009/01/15(木) 23:10:34
あほなの?しぬの?つけ忘れた。
0197デフォルトの名無しさん2009/01/15(木) 23:14:50
>>190
*pt1は'n'なので、'n'+1で'o'
0198デフォルトの名無しさん2009/01/15(木) 23:29:28
>>195
copyとかtransformとかfor_eachとか読み取ったのが捨てられて構わないアルゴリズムに活路を見出すんだ。
0199デフォルトの名無しさん2009/01/16(金) 05:01:52
再帰ってどこまで深くできるんですか?
戻ってこられるように元の場所を保持し続けたらいつかは限界がくると思うんですが
0200デフォルトの名無しさん2009/01/16(金) 05:20:28
スタックが溢れるまで
0201デフォルトの名無しさん2009/01/16(金) 05:23:02
場合によっては永遠に
0202デフォルトの名無しさん2009/01/16(金) 06:01:04
goto文を使うと最適化が無効になると書いてあったんですが
全体が無効になるんですか?それとも使用している関数内で無効になるんですか?
0203デフォルトの名無しさん2009/01/16(金) 06:05:20
迷路を再帰で脱出するプログラムがあったので、あまり大きな迷路は無理なのかなーと
保持するのに使うメモリ容量がわかりませんが、32bit使うとしたら、1Mまで再帰中に変数を使わなかったとして
250k階層まで深くできるってことですか?
0204デフォルトの名無しさん2009/01/16(金) 06:06:08
特定のコンパイラでそういうこともあるかもしれないが一般的な事象ではないな。
0205デフォルトの名無しさん2009/01/16(金) 06:09:31
例外処理は仕組みがわかってもどこで使えばいいのかわからず活用できないでいます。
例外が発生しそうな部分を囲むってあるんですが、場所がわかるなら1行をtryで囲めばいいですよね?
mainの次のネストで囲って全プログラムに適応した方が2か所以上例外が出る場合は面倒がないし、1回で書ける
とかいう理由で使えばいいんでしょうか?
0206デフォルトの名無しさん2009/01/16(金) 07:20:37
template<typename T>
typedef std::vector<T *> pointers<T>;

pointers<int> int_ptrs;

ということはできませんか?
0207デフォルトの名無しさん2009/01/16(金) 07:27:07
>>205
1行を囲むような try は、たぶん適切な使い方じゃない。
一般的なコンソールアプリケーションだと main() にひとつ try を
置くだけで十分なことがほとんど。
C++ FAQ "[17.13] I have too many try blocks; what can I do about it?"
http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.13

こっちも参考になるかもしれない。
C++ FAQ "[17.12] Exception handling seems to make my life more difficult; clearly I'm not the problem, am I??"
http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.12
0208デフォルトの名無しさん2009/01/16(金) 07:33:43
>>206
無理
0209デフォルトの名無しさん2009/01/16(金) 07:34:52
>>206 >>130-131

>>133
↓こんなのが使えるかもしれない。テンプレートメタ関数ってやつね。

template<typename T>
struct vector_of { typedef std::vector<T> type; };

vector_of<int>::type int_ptrs;
0210デフォルトの名無しさん2009/01/16(金) 08:31:07
>>205
×適応
○適用
0211デフォルトの名無しさん2009/01/16(金) 11:41:14
>>209
>>134
0212デフォルトの名無しさん2009/01/16(金) 14:32:59
#include <iostream>
class X {
public:
void show() { std::cout << "X" << std::endl; }
};

class Y : public X {
public:
void show(int) { std::cout << "Y" << std::endl; }
};

int main()
{
Y y;
y.show();
}
ってしたらこんぱいるできないんですがなんでですか?
0213デフォルトの名無しさん2009/01/16(金) 14:48:29
宣言にはセミコロン必要。
0214デフォルトの名無しさん2009/01/16(金) 15:04:49
>>212
オーバーライドされたから。
y.X::show();
0215デフォルトの名無しさん2009/01/16(金) 15:05:06
>>212
Y::show によって X::show が隠されるから。
両者は別物で、両方をまたがってオーバーロード解決はできない
0216デフォルトの名無しさん2009/01/16(金) 15:08:56
YのshowがXのshowを隠蔽するから。

class Y : public X {
public: using X::show;
 (略)
};
というように書けば、Yの中でshowがX::showを隠蔽していても、X::showが選択肢に追加される。

return 0;
0217デフォルトの名無しさん2009/01/16(金) 15:32:10
g++,cygwinです
1.ファイルの有無を確認する方法はありますか?
  Cでは読み込み専用のファイルオープンでファイルの存在確認した後上書き確認の表示してましたが、C++も同様(ifstreamで確認)ですか?

2.int型を16進バイナリで出力したい
  std::ofstream ofs_out( filename, std::ios::out | std::ios::binary );
  oofs_output << std::setw(4) << std::setfill('0') << std::hex << 0xFFFF;
  このコードでは出力先にFFFF(0x46464646)がそのまま表示されますが、どうすればファイルにバイナリで0xFFFFを出力できますか?

3.string->int でエラーを検出したい
  std::istringstream iss(str);
  int i;
  iss >> std::hex >> i;
    (または、i = boost::lexical_cast< int >( str ); )
  このコードで、str="123w"の場合、i=0x123となりそのまま実行されますが、エラーとして処理したいです。
  strtol関数の他に何か方法はありますか?

お願いします。
0218デフォルトの名無しさん2009/01/16(金) 16:25:14
>>217
1. それでもいいでしょう。
2. oofs_output << 0xFFFF;
3. if (!(iss >> std::hex >> i).eof()) { /* error handling */ }
0219デフォルトの名無しさん2009/01/16(金) 19:58:35
>>203
関数コールするたびに、引数の合計分と、関数を出たときに戻るアドレス分スタックが消費される。
0220デフォルトの名無しさん2009/01/16(金) 19:59:19
消費スタックサイズ量を保持する分もスタック使ったかも
0221デフォルトの名無しさん2009/01/16(金) 20:09:48
>>218
ありがとうございます。
1は実装してませんが後でやってみます。3はできました。
2は10進のテキスト(ASCII)で表示され、0xFFFFは出力されませんでした。
書き忘れてしまって申し訳ないのですが、欲しい出力形式はint型変数の下位2バイト、16進数4桁(0x0000〜0xFFFF)です。
  int var[10] = {0,1,2,3,4,5,(.....)}; //ここに出力したいデータが入っている
  std::ofstream oofs_output( "out.txt", std::ios::out | std::ios::binary );
  for(int i=0; i<5; ++i)
    oofs_output << std::setw(4) << std::setfill('0') << std::hex << var[i];
としたとき、
  > od out.txt -x
  0000000 0000 0001 0002 0003 0004 0005
という出力を得たいです。実際はASCIIコードでこうなってしまいます
  > od out.txt -x
  0000000 3030 3030 3030 3031 3030 3032 ...

下のように共用体で実装したら意図した結果が得られましたが、
代入のし直しは無駄な気がしてあまりやりたくないです。
  int var[10] = {0,1,2,3,4,5,(.....)};
  union test{
    char c[4];
    int i;
  }ut;
  for(int i=0; i<10; ++i){
    ut.i = var[i];
    oofs_output << ut.c[0] << ut.c[1];
  }
0222デフォルトの名無しさん2009/01/16(金) 20:24:38
write使え
0223デフォルトの名無しさん2009/01/16(金) 20:34:35
WindowsでVisual C++ 2005を使っています。

isgraphでsjisの2バイト文字も判定させるにはどうすればいいでしょうか。
他に有用なライブラリがあれば教えてください。
0224デフォルトの名無しさん2009/01/16(金) 20:48:17
>>222
char型にする必要はありますか、、
0225デフォルトの名無しさん2009/01/16(金) 20:55:40
>>223
_ismbb系
0226デフォルトの名無しさん2009/01/16(金) 20:56:43
板違いかもしれませんが、
C言語のライタとコンパイラの機能をもつGCC Developer Liteというソフトがインストールできません。
ファイルを開く、実行、言語選択まで進めるのですがその後エラーを知らせるメッセージが表示されインストールができません。
8.3filenameというフォーマットに私のPCが対応していないらしいのです。調べたところ、8.3filenameはMicrosoft の初期の
OSのフォーマットで、Windows XPも対応しているようなのです。
原因のわかる方、何か思いついた方、何かアドバイスをいただけたら非常に助かります。

・表示されたメッセージ
Your PC dose not support 8.3filename format.
Cannot continue installation of this program.

・インストールしようとしたファイル
GCC Developer Lite Ver.2.1.0.20r2 GDLFull2.1.0.20r2.exe (81Mb)
サイト
http://www.besttechnology.co.jp/download/

・私のPC環境
購入元
マウスコンピュータ
OS
Microsoft Windows XP Home Edition Version 2002 Service Pack 3
CPU
Intel(R) Core(TM)2 CPU T7200 2.00GHz
メモリ
2GB
02272172009/01/16(金) 21:00:43
>>222
こうですね、スマートにできました、ありがとうございました。
oofs_output.write( (char*)&var[i], sizeof(int)/2);
0228デフォルトの名無しさん2009/01/16(金) 21:05:43
printfで表示するとき
%3.1fだとすると

3ケタで小数点は1ケタまで表示ですが

1.255とかだったら

1.2ですけど.も桁数にカウントするんですか?
0229デフォルトの名無しさん2009/01/16(金) 21:10:57
しません
0230デフォルトの名無しさん2009/01/16(金) 21:12:17
桁数って考か文字列の幅って考えだから
0231デフォルトの名無しさん2009/01/16(金) 21:52:12
1.255で"%3.1f"なら1.3だな。
0232デフォルトの名無しさん2009/01/16(金) 23:16:19
>>213
なんの話をしてるんですか?
>>215-216
ありがとうございました
0233デフォルトの名無しさん2009/01/16(金) 23:26:25
初歩的な質問ですが・・・
よく関数のオーバーヘッドと言うものを聞くのですが、これは
class A
{
void funcA();
void funcB();
void funcC();
}
とあった場合に、funcA〜funcCの中から呼ばれた関数を探し当てるのにかかる時間のことという理解でいいでしょうか?
つまりメンバ関数の数が増えるほどかかる時間は多くなる、、ということかと思っているのですが。
そしてそれを避けるためにinlineが存在すると。
0234デフォルトの名無しさん2009/01/16(金) 23:38:48
探すのなんてリンク時にやることだ。
実行時にそんなことしない。

関数呼び出し時には
・ リターンアドレスをスタックに積む
・ 命令の実行位置を関数のあるところに移動する
という処理が必須。
関数から戻ってくる際には
・ リターンアドレスを読み出す
・ 命令の実行位置をリターンアドレスに移動する
という処理が必須。
メモリアクセスとジャンプは両方とも遅い処理。
0235デフォルトの名無しさん2009/01/16(金) 23:39:38
>>233
探し当てる時間というのはまぁある意味あってるが、少し理解よくない感じに間違ってる

関数の呼び出し元には、どこに関数があるかが書いてあって、それを元に関数に飛ぶ感じに近い
つまりメンバ関数増えても探すのに時間がかかるようになることはない
0236デフォルトの名無しさん2009/01/16(金) 23:40:05
CやC++の場合、それはコンパイル時に決まる事柄。
オーバーヘッドとされるのは、実際の実行位置の変更や引数・戻り値の受け渡し。
02372332009/01/17(土) 00:11:49
>>234,235,236さん、ありがとうございます。
こんなに早くわかりやすい返信が来ると思いませんでした。。

つまり関数を呼ぶときには、戻ってこないと駄目なので自分の位置を記憶してから
別の関数に飛ぶということですね。
それがinline関数だと直にその関数が呼ばれた場所におかれるので記憶も飛ぶ必要も
無くなるということがわかりました。
両方とも遅い処理なのでしたら、かなり実行速度を気にするプログラムを書く場合は
要所要所でinlineを使ったほうがいいということですか。。
0238デフォルトの名無しさん2009/01/17(土) 00:18:51
いいえ、関数を静的にしたら後はコンパイラに任せてしまいましょう。
0239デフォルトの名無しさん2009/01/17(土) 00:20:08
命令もメモリ上に置いてあって
命令を実行するのもメモリアクセスが必要だから、
キャッシュに載るくらいコンパクトな方が
キャッシュ効率は良くなる。
大きな処理を inline 化して、それが inline 展開されまくると、
逆に遅くなるなんてこともある。
あるいは、速くはなったけど、ファイルサイズが妙に肥大化したり。
まあ、実際には inline にしても inline 展開されるとは限らないけどね。

どんな処理を inline 関数にするのがベストなのかは難しいところだけど、
inline 関数の中身は短い1文かそこら程度で終わるもののみにするのが一般的。
0240デフォルトの名無しさん2009/01/17(土) 00:20:44
>>234
関数呼び出し時にリターンアドレスをスタックに積むとは限らない
リンクレジスタを持つCPUだったり
末尾の最適化で消されたり
0241デフォルトの名無しさん2009/01/17(土) 00:21:40
それを言ったら、inline じゃなくても最適化で inline 化されたり。
0242デフォルトの名無しさん2009/01/17(土) 00:22:51
>inline 関数の中身は短い1文かそこら程度で終わるもののみにするのが一般的。
アナクロな発想は身を滅ぼす典型ですね。
0243デフォルトの名無しさん2009/01/17(土) 00:26:54
inline 関数はヘッダに書かなきゃいけないから、
再コンパイル範囲が広くなってしまう。
だから複雑な処理を書いたら、
修正が必要になった時に場合によっては面倒臭いことになる。
そういった意味でも複雑な処理を書かないのは普通だ。
0244デフォルトの名無しさん2009/01/17(土) 00:32:46
>>243
>238
0245デフォルトの名無しさん2009/01/17(土) 00:34:20
全部静的とかありえねー。
趣味プロかよ。
0246デフォルトの名無しさん2009/01/17(土) 00:35:05
inline つけたら展開しちゃって遅くなるって実際ありうるの?
早くなりそうなら普通の関数を展開してもいいよっていうオプションがあるぐらいだし、
コンパイラがうまいこと判断してくれそうな気がなんとなくするんですが
0247デフォルトの名無しさん2009/01/17(土) 00:35:08
そんなときはオブジェクト間最適化を備えたコンパイラを使えばOK。
0248デフォルトの名無しさん2009/01/17(土) 00:35:47
テンプレートのせいでinlineの有無にかかわらずヘッダに書かざるを得ないことのほうが多い。
0249デフォルトの名無しさん2009/01/17(土) 00:37:17
>>246
gccの例だけど、インライン展開によってオブジェクトモジュールが大幅に大きくなってしまうケースで且つ、
インライン展開されたコードが殆ど実行されない場合に、ロード時間を含めて計測すると遅くなったことはある。
逆に言えば、余程の事がない限り遅くなるようなケースはないと考えていいと思う。
0250デフォルトの名無しさん2009/01/17(土) 00:41:12
テンプレートは仕方が無いよね。
面倒臭いからクラス宣言内で関数実装しちゃうから
全関数がinlineになっちゃう。
0251デフォルトの名無しさん2009/01/17(土) 01:55:06
>>246
関数がある程度の大きさを持っていて、
しかもその関数がありとあらゆるところで使われまくってると
出力コードが肥大化して、キャッシュヒット率が下がって遅くなるかも。
0252デフォルトの名無しさん2009/01/17(土) 01:56:10
>>251
あらゆるところで呼ばれる関数ならキャッシュに居つくんじゃねーの
■ このスレッドは過去ログ倉庫に格納されています