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

C++相談室 part82

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

前スレ
C++相談室 part81
http://pc12.2ch.net/test/read.cgi/tech/1273407971/
02372352010/06/18(金) 17:37:20
すいません自己解決しました

>>236
マクロ無しでも余裕でした
0238デフォルトの名無しさん2010/06/18(金) 19:51:40
>>234
gcc 4.3以降なら-Wconversionで警告出せるよ。
警告出ないと確かに怖いね。
0239デフォルトの名無しさん2010/06/19(土) 01:43:51
Windows上のアプリケーションから、直接システムコールを呼び出して、ヘッダーファイルを
インクルードせずにプログラムを作るには、一体どうしたらいいんでしょう?

色々と調べ回ったのですが、大体がLinuxでのことしか書いてないし、Windowsでのもの
も、実際にコードにしたら、Windowsから不正だのなんだのと言われて、プログラムが止まってしま
うんですが…

例えば、int 21hとか
0240デフォルトの名無しさん2010/06/19(土) 01:45:35
マシンコードとかアセンブラだろ
常識
0241デフォルトの名無しさん2010/06/19(土) 03:28:08
>>239
ヘッダーインクルードを忌避する理由は何?

Windows API (Linux のシステムコールに相当) を呼び出すには call 命令を使うが、その
飛び先 (API を提供している DLL のエントリポイント) をリンクするのはアセンブラでは
煩雑と言うか面倒と言うか忘れたと言うか、使用するアセンブラによる。
API を呼び出すのにかかるコストは、C/C++ の関数形式でもアセンブラの call 命令でも
全く変わらない。
せっかく C++ なのだから、素直に windows.h をインクルードするのが吉。

int 21h で有名なのは MS-DOS ファンクションコールだが、Windows アプリでは (デバイス
ドライバを書いて特権を取得しない限り) そもそも int 命令が禁止されていて、MS-DOS
ファンクションコールは一切使えない (プログラムが不正終了するのはおそらくそのせい)。
MS-DOS アプリが動作するのは、MS-DOS ファンクションコールがエミュレートされている
から (64bit OS では 16bit アプリをサポートしないため MS-DOS アプリは動作しない)。
0242デフォルトの名無しさん2010/06/19(土) 04:55:33
windowsAPIも最終的にはCPUやGPU命令呼び出すから
それを直にやりたいんだろ。
アセンブラ。
0243デフォルトの名無しさん2010/06/19(土) 05:41:16
APIでできる事を自分でやるって、車輪の再開発をしたいって事?
0244デフォルトの名無しさん2010/06/19(土) 07:05:44
>>242
その方法を自分で調べられん奴が一体何をするつもりなんだろうね
0245デフォルトの名無しさん2010/06/19(土) 08:44:24
ヘッダをインクルードしたくないだけなら、必要な宣言をコピーすればいいじゃない
0246デフォルトの名無しさん2010/06/19(土) 08:50:18
疑問に思ったんですが、関数オブジェクトってどういう使いどころがあるんでしょうか。
STL以外での使い道に心当たりがある方お願いします。
0247デフォルトの名無しさん2010/06/19(土) 08:55:18
DOS時代なら特権レベルとかなかったから好き放題だったんだけどねえ
今はintとかin/outとかhaltとか好きに呼べない
ま、安全のためだから仕方がないが
0248デフォルトの名無しさん2010/06/19(土) 15:59:10
自作のコンテナのイテレーター作るときに気を付けること(iterator_tagの設定など)をまとめたサイトってありますかね?
0249デフォルトの名無しさん2010/06/19(土) 20:30:21
>>248
STLで足りない理由を明確にすることかな
0250デフォルトの名無しさん2010/06/20(日) 02:09:03
>>248
作り方: http://msdn.microsoft.com/en-us/magazine/cc301955.aspx
規格(の草案): http://www.kuzbass.ru/docs/isocpp/lib-iterators.html#lib.iterator.requirements
0251デフォルトの名無しさん2010/06/20(日) 06:28:27
C++で
#define YAMA 0
#define KAWA 1
#define HAIRETUNOKAZU 20

とかを使いまくってるのですが、これは話にならないくらいの糞コードなんでしょうか?

static const HAIRETUNOKAZU = 20
みたいにするのが業界標準なんでしょうか?
0252デフォルトの名無しさん2010/06/20(日) 06:35:44
他にも関数作成時は
void kansuu(int number);
みたいに書きまくってるけど
void kansuu(const int number);

for文も
for( a=0 ; a<10 ; a++ )
みたいに書きまくってるけど
for( a=0 ; a<10 ; ++a )

if文も
if( n=10 )
と書きまくってるけど
if( 10=n )

と書かないと業界では鼻で笑い飛ばされて帰っていいよと言われる糞コードなんでしょうか?
0253デフォルトの名無しさん2010/06/20(日) 06:38:42
for文に限ってはほんのほんのほんお少しだけ当てはまる
他については決してそんなことはないというか、
void kansuu(const int number) ってのは void kansuu(int number) と同じシグネチャだから
逆に混乱を招きかねないって意見も多くあるし、
if ( 10 == n ) についても同じ
0254デフォルトの名無しさん2010/06/20(日) 06:49:13
なるほど、ありがとうございました。
for文は++aのがデータのメモリ間のコピーだかなんだかの処理がa++より一回少なくて高速だと聞いたのですが、
それほどその程度の速度を意識したことなかったし、大抵の初心者サイトで最初に教えられるのはa++だから惰性で続けてました。

ほかにも構造体を関数へ渡すときは

kansu(KOUZOUTAI)
void kansu(KOUZOUTAI)

kansu(&KOUZOUTAI)
void kansu(*KOUZOUTAI)

kansu(KOUZOUTAI)
void kansu(&KOUZOUTAI)

みたいないろんなやり方があって自分は2番目を常用してますが、これは好みでしょうか?
DirectxのSDKなどでは2番目で使用する前提の関数が多く用意されてるのでこれがプログラマ達の標準だと思ってました。
他の方でも知っておられたら教えてください。
0255デフォルトの名無しさん2010/06/20(日) 07:29:42
++aがいい。組み込み型なら別に気にしなくてもいいけど、用がなければ前置でいい。
10=nというその例のようなミスを防ぐためにはいいのかもしれないけど、それは強制しないし
n=10と書いても警告が出るからn=10を推奨。10=nは逆に禁止したいぐらい。
値を変更するなら3番目、kansu(*KOUZOUTAI)のtypoだよね?
変更しないならconst参照で受けるのがいい。
鼻で笑い飛ばして帰っていいよとは言わないけど、上記のようなことを説明をしつつ伝える。
0256デフォルトの名無しさん2010/06/20(日) 07:38:26
OpenCVのC++インターフェースとかは入力パラメータがconst参照渡し、出力パラメータが非const参照渡し
Googleのコーディング規約では入力パラメータがconst参照渡し、出力パラメータがポインタ渡しになってるな。
どっちにしろ値を渡す目的ではconst参照渡しを使うのがいいと思う。
0257デフォルトの名無しさん2010/06/20(日) 08:00:54
なるほどありがとうございました。
自分で組んでる分にはわざわざconstなんて付けないし、
人との共同でも値変更があるかはプログラム設計書に明記してりゃいいやと思ってたけど、
安全で安心ではありますね。
0258デフォルトの名無しさん2010/06/20(日) 08:05:26
コンパイラが勝手にconstチェックしてくれるなんて使わなきゃ損だね
0259デフォルトの名無しさん2010/06/20(日) 08:26:34
>>255
1番目は値渡し(コピー)。
2番目はポインタ渡し。
3番目は参照渡し。

のつもりじゃないだろうか。
0260デフォルトの名無しさん2010/06/20(日) 08:34:40
ttp://codepad.org/pnRhDYaP

ポインタ派参照派どちらの派閥をとわずご満足いただけます
0261デフォルトの名無しさん2010/06/20(日) 08:36:16
たまに他言語使ってconst参照相当の物が無いと不安になって心が押しつぶされそうになる
0262デフォルトの名無しさん2010/06/20(日) 09:00:11
C#使っていると、constのような最小限のチェック機構が無いのは何でだろうと悩んでしまう。
0263デフォルトの名無しさん2010/06/20(日) 11:58:09
勉強しろw
0264デフォルトの名無しさん2010/06/20(日) 12:15:56
Immutable保証するやつはないだろ
そもそもメソッドのパラメータとして記述できるのはparamsとrefとoutだけじゃね
0265デフォルトの名無しさん2010/06/20(日) 12:25:40
c#の参照渡しで書込み保護できないとか危険卓
0266デフォルトの名無しさん2010/06/20(日) 12:31:13
まぁC#はC++と違って何もつけなくても間接参照できるし
ref使うのは特殊なケースだろう

間接参照でImmutable保証出来ないのはJavaにしろPythonにしろ同じだし
0267デフォルトの名無しさん2010/06/20(日) 13:48:19
ポインタが無効かどうか知るには管理者からboost::weak_ptrを渡してもらえばいいですか?
0268デフォルトの名無しさん2010/06/20(日) 14:33:30
すまん、const参照渡しって概念は何となく分かるんだが、
const参照渡しが推奨される理由が分からないorz

constポインタ(?)とかじゃダメなの?
0269デフォルトの名無しさん2010/06/20(日) 14:38:25
参照ならNULLが無い
const参照ならテンポラリオブジェクトも取れる
そしてクライアントの手間が省ける
0270デフォルトの名無しさん2010/06/20(日) 16:44:04
>>259
あわわ。寝ぼけてたみたいでorz
指摘ありがとうです。

>>257でちゃんと伝わってたようで安心した。
0271デフォルトの名無しさん2010/06/20(日) 18:36:12
リソースが限られてる組み込みとかって、
templateよりdefine関数の方が一般的?
0272デフォルトの名無しさん2010/06/20(日) 18:50:47
と公言していた某プロジェクトが今どうなったか知らぬのか
# defineは関数ではない
0273デフォルトの名無しさん2010/06/20(日) 18:54:58
確かにdefine関数っていうのはおかしいか
マクロ展開
0274デフォルトの名無しさん2010/06/20(日) 19:49:27
>>270
うむ。orz
0275デフォルトの名無しさん2010/06/20(日) 20:16:02
まあ関数型マクロと呼ぶし、
プリプロセッサにとっての関数とも言えるので
いいんじゃない
0276デフォルトの名無しさん2010/06/20(日) 20:16:55
ですね
0277デフォルトの名無しさん2010/06/20(日) 21:06:04
引数付きマクロのことかい
0278デフォルトの名無しさん2010/06/21(月) 00:09:08
>>241
ヘッダーインクルードを忌避しているわけではなくて>>243が言っている通り、車輪の再開発をしたいのです。
まだ学生の身なので、よりハードウェアに近いところを勉強したくて…


CPUをスーパーバイザモードで動かせば、メモリの好きなアドレスに書き込みが出来るかな、と思って、
ハードウェア直叩きで映像を表示出来れば、DirectX等のコンポーネントを使う時も理解が深まると


>>245
関数プロトタイプ宣言を用意してみても、実体が無い関数だからリンクが出来ないと言われております
0279デフォルトの名無しさん2010/06/21(月) 01:06:48
へえ
0280デフォルトの名無しさん2010/06/21(月) 01:18:57
>>271 template が何か実行時のリソースを浪費するとでも思ってるのか?
0281デフォルトの名無しさん2010/06/21(月) 02:18:44
ループがあると関数はinline展開されない事が多いな
0282デフォルトの名無しさん2010/06/21(月) 03:45:52
>>280
exeが大きくなるぶん消費量は増えるのでは
浪費というとおかしいけど。
0283デフォルトの名無しさん2010/06/21(月) 03:53:19
>>282 マクロだと「exeが大きく」ならないの?どうして?
0284デフォルトの名無しさん2010/06/21(月) 04:10:45
>>283
>>280は流れをみれば、defineはリソースを浪費するが、templateは浪費しないだろ、って論調じゃん
そうじゃなきゃそのレスにはならない
0285デフォルトの名無しさん2010/06/21(月) 04:12:53
defineとtemplateってどっちが肥大化すんの?
defineの方が大きくなりそうといえばなりそうなんだけど。
0286デフォルトの名無しさん2010/06/21(月) 04:13:24
>>284 そんなことは言っていない。それに、質問してるだけなのに「論調」とか言われても困る。
0287デフォルトの名無しさん2010/06/21(月) 12:18:33
>>278
残念ながら、Windows は抽象化というものを行っており、デバイスドライバを除くすべての
ソフトはスーパーバイザモードに移行できず、従ってハードウェアに近いコードを書く事は
できない。
ただし、抽象化というのは全く異なるハードウェア上で同一のバイナリが実行できるという
点で歓迎すべきものと同時に、ユーザーモードのアプリに下手な動作をさせずシステムを
クラッシュさせないという安定性の確保の観点から重要なもの。

どうしてもハードウェアを直叩きしたいという場合にはデバイスドライバを書くしかないが、
それはシステムの安全を考慮した高い品質のコードを慎重に書かねばならない上、それ
をするにはそもそもハードウェアの仕様を知らなければならないが大抵の場合メーカーは
ハードウェアの仕様を公開していないため事実上不可能 (メーカーの提供するデバイス
ドライバをリバースエンジニアリングして仕様を解析するという手段も無いではないが、それ
はそれでプログラミングとは別のスキルが要る)。

Windows 上で普通にプログラミングしている限り、ハードウェアに直接触れる事はできない
し、意識する必要も無い。
せいぜいが DirectX を利用したらハードウェアに近い事をした、と思っておく程度。
ミドルウェア・ファームウェア開発者を目指すのでなければ、それ以上の知識は不要だし、
邪魔になる事もある。

これ以上の話はスレ違いかな?
0288デフォルトの名無しさん2010/06/21(月) 12:30:24
そしたらアセンブラにCPU命令があるのはなぜだ。
0289デフォルトの名無しさん2010/06/21(月) 12:44:09
>>288おまえはOSの勉強からはじめろよ。
あとにどとくんな。
0290デフォルトの名無しさん2010/06/21(月) 12:45:55
>>288
アセンブラは基本的に全ての命令をサポートしてるよ。ただそれだけ。
そうじゃなければOSのコア作る人はどうすればよいのかと。
0291デフォルトの名無しさん2010/06/21(月) 13:19:35
Linuxつかったほうがいいんじゃね?
0292デフォルトの名無しさん2010/06/21(月) 16:02:15
>>288
今流行のマルチコアを活用したプログラムとかSSE2/SSE3/SSE4をバリバリ
使ったプログラムを書くにはインラインアセンブリしかあるまい。

そういう意味ではx86-64でC言語でインラインアセンブリを禁止したのはおかど
違いだと思う
0293デフォルトの名無しさん2010/06/21(月) 16:06:50

> 残念ながら、Windows は抽象化というものを行っており、ハードウェアに近いコードを書く事はできない。
0294デフォルトの名無しさん2010/06/21(月) 16:07:53

> Windows 上で普通にプログラミングしている限り、ハードウェアに直接触れる事はできないし、意識する必要も無い。
0295デフォルトの名無しさん2010/06/21(月) 17:18:15
>>293-294
何ですかコレ
0296デフォルトの名無しさん2010/06/21(月) 17:58:16
>>295
触るな
バカがうつるぞ
0297デフォルトの名無しさん2010/06/21(月) 17:59:46
>>295
触るな
バカがうつるぞ
0298デフォルトの名無しさん2010/06/21(月) 18:06:01
>>296-297
何ですかコレ
0299デフォルトの名無しさん2010/06/21(月) 18:13:57
バカがうつるとどうなるのか身をもって教えてくれた>>296-297に感謝
0300デフォルトの名無しさん2010/06/21(月) 18:19:14
お断りします。
0301デフォルトの名無しさん2010/06/21(月) 21:21:51
特権レベルを知らない馬鹿はスルーしておけば良い
0302デフォルトの名無しさん2010/06/21(月) 21:28:38
>>292
インラインアセンブリなんてもともと曲がったものだからな
アセンブラで書く必要のあるものは割り切ってアセンブラで書くべきで
それをまだ asm が予約語だからとしがみついてるアフォが板杉
0303デフォルトの名無しさん2010/06/21(月) 21:34:18
それだといちいち何らかのジャンプが発生するだろ
効率悪い
0304デフォルトの名無しさん2010/06/21(月) 21:45:44
間に C++ を介在させるからだよ
命令シーケンスの連続性に意味があるコードに高級言語を混ぜる書くアフォは氏んでいい
0305デフォルトの名無しさん2010/06/21(月) 21:47:54
触っちゃいけない子だったか
0306デフォルトの名無しさん2010/06/21(月) 21:50:00
ノーアンサー?
0307デフォルトの名無しさん2010/06/21(月) 21:53:07
WinUSBやったことありますか?
0308デフォルトの名無しさん2010/06/21(月) 22:55:45
クラスの依存でつまずきました… orz

class AbstractHoge {
  (略)
};

class A : public AbstractHoge {
public:
  B toB();
};

class B : public AbstractHoge {
public:
  A toA() {
};

これが通らないのは、仕様?
0309デフォルトの名無しさん2010/06/21(月) 22:57:04
うん。
0310デフォルトの名無しさん2010/06/21(月) 22:58:01
うん。class B;ってClass Aの前に書くといいよ。
0311デフォルトの名無しさん2010/06/21(月) 23:24:11
>>285
templateは型ごとに関数が個別に作られる
マクロはその場に展開

後は分かるな?
0312デフォルトの名無しさん2010/06/21(月) 23:29:02
templateがインライン化されるような状況だと
どちらでも変わらないかもね
普通は#defineの方が肥大化するだろうけど
0313デフォルトの名無しさん2010/06/21(月) 23:30:37
どっちともいえないな。
複数箇所へ埋め込んだらdefineがおおい。
メンバ関数が多くあれば使わない部分まで生成されるテンプレートが大きい。
0314デフォルトの名無しさん2010/06/21(月) 23:37:48
いや、使わない部分は生成されないぞ
0315デフォルトの名無しさん2010/06/21(月) 23:44:42
gccでテンプレートが展開された後のコードを見ることってできますか?
0316デフォルトの名無しさん2010/06/21(月) 23:49:42
>>271
組み込みの場合、引数付きマクロはテンプレートの代りに
用いられるわけではなくて、レジスタやメモリマップドI/Oへの統一的な
アクセスを提供するためとかじゃないかね
他には既存Cシステムからの流れからというのもあるだろうね
それとメーカーの提供してるサンプルがCだったりすることも影響してると思う
0317デフォルトの名無しさん2010/06/21(月) 23:57:51
functionつかえ。
defineは複数箇所に展開されたらかさふえる。
サイズがでかくなって良い場合はdefine。
しかし単一箇所にコードがあった方が速度上がるだろうから
define使う利点無し。
0318デフォルトの名無しさん2010/06/22(火) 00:01:41
void Foo( int x ){ Boo( x ); }
みたいな関数でもインライン展開しない方がいい?
0319デフォルトの名無しさん2010/06/22(火) 00:04:31
何を気にしてるんだかさっぱり分からん
0320デフォルトの名無しさん2010/06/22(火) 00:24:10
>>310
ありがとうございます。
0321デフォルトの名無しさん2010/06/22(火) 01:12:46
現在、windows 7でレジストリのアクセス許可の設定を行っているんですが、
SeSecurityPrivilegeが有効になっていないためエラーになります。
そのコードがC++からコマンドラインを呼び出して設定しているという形になっています。
コマンドラインで使用しているツールはsubinaclです。
SeSecurityPrivilegeを有効にするための関数などC++であったら
ヒントでもいいので教えていただきたいのですが
何卒よろしくお願いします。
0322デフォルトの名無しさん2010/06/22(火) 01:47:53
exec()かなんか使ってsubinaclコマンドを実行しようとしたら、
"SeSecurityPrivilegeが有効になっていない"みたいなエラーが出るって話かな。

C言語レベルの話だし、Windows限定じゃん。WinAPIのスレで質問した方がよくね。
http://pc12.2ch.net/test/read.cgi/tech/1274949734/l50
0323デフォルトの名無しさん2010/06/23(水) 01:04:11
演算子のオーバーロードがややこしいのは俺だけ?
0324デフォルトの名無しさん2010/06/23(水) 01:05:18
ややこしいからgoogleだと禁止
0325デフォルトの名無しさん2010/06/23(水) 03:22:36
operator= もだめなのか
0326デフォルトの名無しさん2010/06/23(水) 05:30:22
>>323
関数オブジェクトとかコピーコンストラクタとかfriendなoperatorとか、お前のノーミソはパニックだろw
0327デフォルトの名無しさん2010/06/23(水) 11:48:23
ぶっちゃけそんなにややこしいとは思わないけど
交換則が成り立たない加法演算子とか、反対称則の成り立たない比較演算子とか定義して、
テンプレートあたりで意図せず使ってしまい、破錠しないかってのはすごい気になる……。
0328デフォルトの名無しさん2010/06/23(水) 11:53:56
演算子の文法で呼び出せるだけで、何をするかはユーザーの勝手だ。
0329デフォルトの名無しさん2010/06/23(水) 12:24:28
>>327
おまえはC++をちゃんと勉強してきたのか?
0330デフォルトの名無しさん2010/06/23(水) 13:24:17
>>327
overloaded operators for classes should behave like operators for builtin types
0331デフォルトの名無しさん2010/06/23(水) 13:36:12
spiritがなかまになりたそうなめでこちらをみている
0332デフォルトの名無しさん2010/06/23(水) 20:04:55
>>327
が言いたいのは
 >>329-330
 > overloaded operators for classes should behave like operators for builtin types
 shouldなだけで守られるとは限らないじゃないか。
 stdのiostreamを思いだそう!
ってことじゃないのかな?

そして>>327が言う問題って、Conceptさんの力があれば解決できるの?
C++0xはよーしらんのだが。
0333デフォルトの名無しさん2010/06/23(水) 20:13:24
>>327
int+hoge が hoge::operator+(int)に一致するようなことを危惧してるの?そんなことはないから。
0334デフォルトの名無しさん2010/06/23(水) 20:14:59
>>333
???
0335デフォルトの名無しさん2010/06/23(水) 21:39:22
>>333
int+hoge
hoge+int
が同じにならない可能性があることを危惧しているのではないのか
0336デフォルトの名無しさん2010/06/23(水) 22:04:21
>>332
Yes
iostreamをはじめ、std::string、boost::format、spiritはいわずもがな。
便利だから使うけど、C++って>>330のようなコンベンションが黙殺される傾向にあるのは確かで……
まぁそれだけなら問題ないわけだが、呼び出す関数側で交換法則が成り立つと思って処理したら
結果は未定義になってしまうんじゃないか?

Conceptはこういうメソッドを持ってるということは認識できるけど、
「正しく」実装されているかについては知ることはできないし、不可能だと思うよ。
■ このスレッドは過去ログ倉庫に格納されています