1 :
デフォルトの名無しさん :
02/11/25 18:12
2 :
デフォルトの名無しさん :02/11/25 18:16
自由と正義の名の下に2ゲット!
./"´:;;::;;;: ::::;::"ソヽ
/ ,ヘ〜-ー'´⌒``ヽ:ヽ
/ ノ 彡:三:三:三:ミ |: \
| |. __,,;;ィ t;;;;,,,_ :ヽ│
| |シ ,ィェァ') (.yェュ、 ミ| |
!r、| ''''''. | | '''''' Y )
ヽ{ ヽ. (r、 ,n) /:: };ノ
し} : 、___二__., ;:::::jJ
!、.:. ´ ..::::... `ノ::::ノ
_,〉、ゝ '""'ノ/:|
__,,ィ';;;;ト `ニニ: ::..ノ|ヽ、 _
-ー''''"";;;;;;;;;;;;ヽ \::::::::/ /;;;;;;;;;;;`''ー-、,,,,__
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ヽ >< /;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"''
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ヽ /|;;;jヽ、/;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
自由と正義の名の下に、このスレにアメリカが介入しました。
以下、大統領に従ってください。
>>1 弱いくせに調子に乗るなよこのジャップ豚(プ
>>2 >>3 スモウレスラーかと思ったら、ただのデブか(プ
>>4 コリアもジャップも同類だろエテ公(プ
>>5 米ばっか食ってんな(プ
>>6 トマホークかますぞ(プ
>>7 エロアニメが文化かよ(プ
>>8 ロリコン必死だな(プ
>>9 イラクの次はお前だな(プ
うにしす
↓タリバソ
↑アソパソマソ
↓エロカイダ
↑ザビエロ
True = Not False まさにトリッキー
>8 True = Not False 証明して下さい
_;main(){(9^_^9);} /* こんなの見た */
14 :
デフォルトの名無しさん :02/12/10 13:38
// 知られざるC言語の演算子 // 標準仕様には入っていない(と思う)のですが、 // 初期ccでサポートされていたこともあり、 // たいていのコンパイラで実装されている知られざる演算子をご存じですか? int main(void) { int a=10,b=7; printf("割ってかける演算子、かけて割る演算子\n"); // 3で割ってから3でかける演算子 a/*=3; // 5でかけてから5で割る演算子 b*/=5; printf("a=%d b=%d\n",a,b); return 0; }
#include <stdio.h> int main (void) { printf ("( ´_ゝ`)フーン\n"); return 0; }
16 :
デフォルトの名無しさん :02/12/10 20:57
前スレのお題を変えてみて…… ◆ある図形内に点が含まれるかどうかを高速に判断する という問題はどう? 図形は、n個の点(x_1,y_1)-(x_n,y_n)で与えられるとしましょう。 n>=3で、(x_n,y_n)と(x_1,y_1)は繋がっていると考えてください。 このn個の点は、隣同士を線で結んでも、線が交わることがないものとします。 高速化のために条件を付加してもOKですが、明記してください (例えば、凹んでいる部分は絶対に無い、n==4である、とか) 難しそう
短形(x1,y1)-(x2,y2)なら、最速は (x>=x1 && x<=x2 && y>=y1 && y<=y2) でいいのかな?
>>14 a=5 b=7 となるだけだが ?
(なんで、b*/=10; にしないんだろう...。)
>>18 コンパイラバグってるよ。アセンブラ出力して確認汁。
>>18 それって古典的なネタじゃん
main() {
printf("%03d\n", 001);
printf("%03d\n", 010);
printf("%03d\n", 100);
}
これといい勝負。
>>21 自分でソース打ち込んで試せ。
ちゃんと自分でエディタを使って打てよ。
あとメモ帳やviみたいな色分けもできんような
エディタはミスしやすいから使うなよ。
>>21 Cなら
// 3で割ってから3でかける演算子
でエラーが出るのが妥当 (でも無いかも知れない)
C++なら
a=5, b=7 ;
で
>>18 で正しい
>>26 今の時代、Cコンパイラにだって
C++のコメントを許容するオプションくらいあるでしょ
10/3*3 なんだから a=9 じゃないの??
>>28 正しいC環境がインストールされていませんね。
>>28 だから自前で書いて試せって。
色付け可能なエディタでな。
a/*=3; b*/=5; は a /*=3; b*/ =5; だから a=5;
まぁ初めて見たやつには面白いネタだったろうな。 初めて見ました。
よく似たネタに、ポインタが指す値で割るというのがあるね。 a = 1/*p;
>>37 普段から
a = 1 / *p;
のように演算子の前後に空白を開けてれば問題ない。
正直、面白かった。
まだよく解かってないヤシがいるみたいだな 俺の事です
まさにトリッキー 楽しかった。
43 :
デフォルトの名無しさん :02/12/19 01:11
age トリッキーの1ってここのスレの人?
前スレのコレすげー・・・ ↓ xor eax, ebx xor ebx, eax xor eax, ebx いただきました。
ax固定の命令を使わなければ 入れ替える必要は、ほとんど無いだろ
46 :
デフォルトの名無しさん :02/12/19 02:14
前スレ読んだら解った。トリッキーの1は前スレの1だね。 すげー盛り上がっててかなりいい感じだったね<前スレの最初の方。 このスレにも降臨してくれないかな・・
47 :
デフォルトの名無しさん :02/12/19 02:46
宿題キボンヌ
漏れはむしろ↓に衝撃を受けた。 int main=0xc3;
0xc3ってx86系のリターンだっけ…?
>>44 最近のCPUではパイプラインが有効に働かず遅くなるだけ。
100 nop 101 jmp 100
repeat loop
;トリッキー
55 :
デフォルトの名無しさん :02/12/19 18:50
#!/usr/bin/perl $x=$_='#!/usr/bin/perl&$x=$_=";&s/\046/\n/g;s/\042/\047$x\047/;print;&'; s/\046/\n/g;s/\042/\047$x\047/;print;
なんで、誰も
>>17 の短形に突っ込んでないの?
おまいら皆アフォ?
矩形(くけい)だろ、ヴォケ
>>56 2ch でその突っ込み...、しかも10日も立ってから...。
はっ !! もしかして本人なのか ?
いや、今日初めてこのスレ読んだ 今前スレ読んでるんだが面白いな 短形ってがいしゅつとかの類かね、素で間違ってそうなんだが
スマソ、前スレのラストのほうでちゃんと矩形って書いてたな
スマソ、知り合いに「たんけい、たんけい」と連発するヤツが居てな いつも突っ込めずに居るんだ(;´д`)ストレスタマルヨー
前スレみたいなノリキボンヌ
スレ汚した詫びにネタ振り 任意の文字列を、10進数に変換するコードを書きなさい。 char *binary = "11011100"; int decimal; /* */ printf("%s is %d\n",binary,decimal);
> 任意の文字列を、10進数に変換するコードを書きなさい。 この文がどれだけ曖昧で意味不明か、自分でわかってる? 数値自体は2進数で「表示」しようと10進数で「表示」しようと 同じ値だから変換もなにもないし、 そもそも元の文字列が何進数を文字列にしたものなのかわからない。 多分、「任意の2進数を表す文字列を数値に直し、10進数として表示しなさい」 って意味だと思うけど。
>65 uzeeeeeeeeeeeee いつも客にうだうだ言ってそう
見りゃ分かるだろ、何か嫌な事でもあったか?
>>67 > 見りゃ分かるだろ、
仕様書もまともに書けない客にこう言われてカリカリしてたんじゃないですか。
69 :
デフォルトの名無しさん :02/12/20 13:41
>>55 だれも反応してくれないけど,地雷だと思った?
実行すると,自分自身を表示するperlプログラムでした.
Cで同じことするプログラム キボンヌ
70 :
デフォルトの名無しさん :02/12/20 13:45
取りあえず職場でXPもどきを導入しはじめてるんだが 仕様書まともに書けない客=普通 客から仕様を上手く引き出せない技術屋=無能 だと思った。
>>69 > 実行すると,自分自身を表示するperlプログラムでした.
それは分かるけど、
> Cで同じことするプログラム キボンヌ
そういう意図が隠されていたとは気づかなかった。
>>70 > 客から仕様を上手く引き出せない技術屋=無能
技術屋つってもいろいろあるわけだが、「客から仕様を引き出す」ってのがSE
の仕事だから、それがうまくできないSEなら無能だな。
>>72 自己レスすまそ。バグ内包してますな。
でもまぁトリッキーでないコードなので修正はやめておきます
>>70 うちはいつまでたっても ひとりXP ですよ
>>62 「もしかしてクケイの事?(笑)」ぐらいにして
最近思うんだが、数年前に比べて格段に質の低いレスを見ると、 このスレに限らずこの板の全体的な(技術or人間)レベルが落ちている 可能性が高いな
まぁ俺がいるぐらいだからな
>>64 どうでしょ?
char *p = binary;
decinal = 0;
while (*p) decimal = (decimal << 1) | (*p++ - '0');
s/decinal/decimal/;
>>79 お前さぁ、それに"10"を渡したらなんて表示されるか考えてみたか?
83 :
デフォルトの名無しさん :02/12/21 01:33
2進数文字列解析 多分最速ではないかと unsigned int d=0,i=sizeof(int)*8; char *p=binary; while(*p!='\0') (*(p++)-'0')?d+=(1<<(--i)):i--; d>>=i;
あ、最速ではないな… 文字列→変数のマップを用意して(以下略)
>>56 char *p="任意の文字列";
long num = (int)p;
「任意の文字列を10進数に変換しろ」だけではこーいう解釈も(無理矢理)成り立つ罠。
元の文字列の条件と、読み取りルールをきちんと書け。
ex.
「'0'と'1'からなる任意の文字列を2進数として読み取り、
結果を数値型変数に格納せよ」
>>85 いや、もうその話題は終わったから
つーか何でそんなに粘着なの?
もろもろの判定を含め、さらにトリッキーに
#include <limits.h>
char *p=binary;
unsigned int c,d=0,i=sizeof(int)*CHAR_BIT+1;
while(((c=*p++-'0')
>>1 )==0&&--i)d=(d<<1)+c;
矩形の問題はどうなったのか気になったり気にならなかったり
更にトリッキーに (評価順はpの再利用を考え)
while(--i&&((c=*p++-'0')
>>1 )==0)d+=d+c;
どの辺がトリッキーなのかと小一時間(ry 七行かぶれで短くしてるだけやん
アセンブラでトリッキーなのいってみよ
Windows上で動くAssembler Virusとか。
某CADソフトのAPIの仕様はカナーリトリッキーです。 なにせ「ファイルを自動で開く」という至極基本的な動作を行う プラグインが簡単に作れない。
>>95 よー知らんけど、それはお前の技術力がないからということはないのか ?
>>95 漏れに技術力があるかどうかは知らんが、
そのソフトのAPIだけでは実現できず(どーやっても選択ダイアログが出る)、
キーストロークのエミュレートしたり、DDEコマンド投げたりせんと実現できん
というのはどう考えても変だと思うんだよ…
ちなみにマニュアルには「スクリプトを実行しる!」みたいな事が書いてあった。
しかも上記の手を使ってもプラグイン実行中に開けない。
(本体がコマンド受付状態になってからでないと開かない)
それはトリッキーなんじゃなくて、クソなだけじゃないか?
>>98 禿同、回避方法がトリッキーだったりするけど。
そのトリッキーはなんかスレ違いの香り 100get
スレチガイスマンカッタ。 オブジェクトGetした後の開放手段がバラバラ (free、delete、独自関数、開放不要のごちゃ混ぜ) とかいった話はマ板でネタにしてきます。 これで業界トップのシェア持ってるというから、驚きなんだよなぁ…
互換性とかの理由からだんだんぐちゃぐちゃになったんじゃなくて 最初からそうなの? Windowsにもメモリ管理のAPIが何種類あることか…
44 は xchg eax, ebx ではあかんか?
>>103 いいと思うけど、例えば 下位6bitだけ交換したいような場合に応用出来るのは >.44
> 下位6bitだけ交換 44 でそんなことができるの?
前スレにこう書いてあったけど、どの程度なんだ? > xchg 命令は遅いのだよ
>>105 AND 直値を入れたら出来た気がするけど…
あ、ゴメン、もうひとつレジスタ使わないと交換出来ないや
>>106 マルチプロセッサ環境ではlockが入るので、
タイトなループでやらかすと酷いことになる。
シングルプロセッサで遅いという話は知らない。
>>112 格好悪いけどこうかな
mov ebx,eax
xor ebx,edx
and ebx,63
xor edx,ebx
xor eax,ebx
>>110 たぶん 勘違いしてると思う P2かP3かで XCHG は
>>44 の3命令と同じ負荷の筈
IA-32マニュアルによると、XCHGはオペランドに関わらず常にLOCKを吐く。
>>113 は嘘を仕込むなよ。
>>115 マニュアルには
XCHG命令には自動的にLOCKプリフィックスが付くものと想定されている
と書かれているが、前後の文意から
LOCKが必要なものは、自分でLOCKしてね♪
と言う意味で、常にLOCK#信号を出す訳では無いに100カノッサ
> xor 3回よりも速い罠 > mov 3回よりも速いみたいだが > push/popは勿論論外(w なの?xchgはパイプライン崩すとかあった気がしたが。 クロック計算は486時代以来してないので最近のは知らんのだが。
パイプライン出てきてからクロック計算する気がしなくなった漏れは、もうだめぽ?
ああ、なるほど。 >XCHG 命令は、LOCK プリフィックスの有無に関係なく、常にLOCK# 信号をアサートする。 これを読んで勘違いしたんだな。でも、 >メモリ・オペランドが参照されていると、 >LOCK プリフィックスの有無、あるいはIOPL の値に関係なく、プロセッサのロッキング・プ >ロトコルが交換操作が持続している間自動的にインプリメントされる。 だから、これは対メモリに関する項だと思うよ。 それに、 >NOP 命令は、XCHG (E)AX, (E)AX 命令の別名ニーモニックである。 だから もし必ず XCHG が LOCK#アサートだとすると NOPでも同じ事になる。 確認したら XCHG eAX,r16/32 uOP数は3みたい
> xchgはパイプライン崩すとかあった気がしたが。 P5ではペアリング不可。 P6以降はu-opに分解される? でもリネーミングならOP数1のような。
スレたてるまでもない質問スレから誘導できました。 スコープ解決演算子の無い(ANSI準拠)Cで グローバル変数を使うときに struct{ int a; //・・・ ・ ・ ・ FILE in; //・・・ }global; と定義して、使うときにわざわざglobal.aとかやってるんですけど 同じ方法とってる人や、もっといい方法を知ってる方いませんかー?
122 :
デフォルトの名無しさん :02/12/26 03:33
void main() { char *p = strcpy((char*)malloc(strlen("hello,world\h")+1), "hello,world\n"); printf(*p) }
>>121 似たようなことを偶にやります。
オレの場合、globalでなく、そのソースのファイル名にちなんだ名前を付けます。
static付けるとマップファイルに出てこなくなるから、
ユニークな名前を付けるために、ファイル名を頭に付けるようにした。
関連するグローバル変数を構造体にまとめるようにし始めた。
そうこうしているうちに全部構造体に押し込むようになってしまいました。
*つけちゃいかんだろ
(^*^)
顔? 後ろから見たケツ?
>>121 それで何か困るの?
まぁ、あとは命名規則などをしっかりとすれば、
グローバル変数との衝突なんてそう簡単には起こらないと思うけれど、
規模によってはあり得るだろうな。
>>106 いまさらだが試してみたガッテン。
改行が多いと怒られたので以下、分割。
#include <windows.h>
#include <stdio.h>
#defineLOOP500000
#define_ALIGN_//align 2
func1()
{
_asm
{
movecx, LOOP
_ALIGN_
f1:movedx, eax
moveax, ebx
movebx, edx
dececx
jnzf1
}
}
func2() { _asm { movecx, LOOP _ALIGN_ f2:xoreax, ebx xorebx, eax xoreax, ebx dececx jnzf2 } } func3() { _asm { movecx, LOOP _ALIGN_ f3:xchgeax, ebx dececx jnzf3 } }
func4() { _asm { movecx, LOOP _ALIGN_ f4:pusheax pushebx popeax popebx dececx jnzf4 } } int prof(void (func)()) { __int64start, end, freq; HANDLEhprocess; DWORDoldclass; hprocess = GetCurrentProcess(); oldclass = GetPriorityClass(hprocess);
Sleep(10); SetPriorityClass(hprocess, REALTIME_PRIORITY_CLASS); QueryPerformanceFrequency((LARGE_INTEGER*)&freq); QueryPerformanceCounter((LARGE_INTEGER*)&start); func(); QueryPerformanceCounter((LARGE_INTEGER*)&end); SetPriorityClass(hprocess, oldclass); return (int)(end-start); } main() { printf("func1 = %d\n", prof(func1)); printf("func2 = %d\n", prof(func2)); printf("func3 = %d\n", prof(func3)); printf("func4 = %d\n", prof(func4)); } 結果 func1 = 6685 func2 = 9706 func3 = 6426 func4 = 10277 xchg が一番早い。xorが一番遅い。
それ*だけ*を繰り返しても意味ないんでは・・・
>>133 そうなんだけどね。一応データとして。
>>134 Pen3 のノートPCでつ。ほかの石だとどうなんでしょう?
>>135 しかも一番遅いのはpush/popだった。鬱
>>137 比率の問題だろ。周波数は関係ないだろ。
それよりもCPUの世代だろ。
OSもあまり関係ないと思うがな。
漏れも周波数は関係ないと思うが、OS は存分に関係ある気がする。
>>140 そうか?
REALTIME_PRIORITY_CLASSで実行してるんだよな?
タイムスライスをまたがるほど長時間のスレッドが動いてる
ようにも見えないんだけど。
>>141 ひょっとして、LinuxとかFreeBSDとか気にしてるのか?
どうみてもWin32のコードだと思うんだけど。
追試のためには、 環境は関係なさそうでも書いとくのが普通では? そんな基本も知らないアホがこの板の多数なのか?
知らん
わざと追試できないようにして、かく乱するのもテクの一つですよ。 まあ、この場合はベンチマークプログラムそのものが無意味っぽいですが。
リアルモードとプロテクトモードで結果変わる? 変わらない?
P6系の場合マニュアル上ではxchgは3μopで1命令ですむのだから 1クロックで1μopの命令が、あと2つ同時に実行出来るはず ( 1クロックで4μopが1つと1μopが2つ同時に実行できる ) 他の命令では少なくとも3命令になってしまうので OSに関係なくP6系ではxchgが1番早い
各環境での結果まだ?
138 のようにごねないで、素直に環境書けばいいのに。 環境書きたくない理由があるのか?
procedure TForm1.Button1Click(Sender: TObject); procedure SwapXCHG(var a,b:Integer) ; asm xchg eax, edx end; procedure SwapXOR(var a,b:Integer); asm xor eax, edx xor edx, eax xor eax, edx end; function RDTSC:Integer; asm RDTSC end; var cXCHG,cXOR,c0,c1,i,j:Integer; var a,b:Integer; begin a:=1; b:=2; cXCHG:=0;cXOR:=0; c0:=RDTSC; for j:=0 to 9 do begin for i:=0 to 9 do SwapXCHG(a,b); c1:=RDTSC;inc(cXCHG,c1-c0);c0:=c1; for i:=0 to 9 do SwapXOR(a,b); c1:=RDTSC;inc(cXOR,c1-c0);c0:=c1; end; Memo1.Lines.Add(Format('XOR=%5d XCHG=%5d',[cXOR,cXCHG])); end; Athron 800M での結果 XOR= 1424 XCHG= 1481 順番を逆転したら逆の結果が出たから、ほぼ同じなんでしょ
最初のやつがOSなどの環境を書かないと、 残りもマネをするんだなあ。
>>152 151を良く見ろ、コードが全く違うぞ。
それ以前の問題だ。
あ、ほんとだ。 var は不要だし、そもそも交換した結果を返してないや。 まあ、時間測るだけだからいいか
>>107 お前はいったい何の時間を計測してんだ?
for や func call やタスクスイッチのオーバーヘッドの方が
大きかったりしないか?
>>129 の方がまだ信憑性ありそうだな。
お前ら
>>129 のコード実行してOS、CPU(ステップ&周波数含む)と共に報告スレ。
漏れはスペースが全部なくなってて挫折しますた。(w
OS云々はともかく、Pentiumに関して言うならば…。 push/pop での交換は確実に遅い。スタック操作を伴なうから プロテクトモードでならメモリ保護チェックが必ず発生してしまう。 #コンパイラの最適化レベルを上げるとcall/retを減らすように #アセンブルコードを出力しようとするのもこの理由による。 xor他による交換の場合は、二つ目、三つ目の演算命令は その前の演算命令によってレジスタ内容が完全確定していないと 演算自体することが出来ないわけだから、それぞれの命令間で パイプラインストールが発生する可能性が非常に高い。 #それぞれの命令間にNOPを挟んでも実行時間に大差なければほぼ間違いない xchg の場合、厳密にはレジスタの内容を交換しているのではなくて、 現在ではレジスタの名前のほうを(CPU内部的に)交換していると思っていい。 なので交換対象レジスタの組み合わせによってはストールしにくい(またはしない) #むかしのCPUでは確かにレジスタ内容自体を交換していた。(RISC系は現在でもそう) #けど多段パイプラインやコード予測機能の絡みもあるので、 #CISC系ではそういうのに影響を与えにくい設計に進化してきている(はず) まあ、純粋培養のソフト屋さんにハード依存の話をしても、 なかなか想像力が付いて来ないだろうとは思うけどね…。
>>156 マジレスカコワルイ
push/popはメモリアクセスする時点で遅いのは確定。
俺の興味はどっちかというとどれ位遅いかだな。
xorやmovによる交換も実質レジスタリネーミングされると
考えればパイプラインストールはほぼ発生してないはず。
129の結果どおりだとすれば、156のとは正反対の
mov/xor 3回よりは xchg の方が早いが、
xchg単体は mov/xor単体よりもずっと遅い
という結果が出てくる。
そもそもCPUの話題でOS他の環境のネタが出てくるところが痛いね。 ここの住民はそのうちメモリ容量とかHDD容量とかビデオチップとか 言い出す予感。
前スレ良かったな〜
>>155 負荷を測るなら for や call の時間込みで測定するのがホントじゃないの?
まあ、ループした方がいいっていうなら
procedure TForm1.Button1Click(Sender: TObject);
procedure SwapXCHG;
var i:Integer;
begin for i:=0 to 100-1 do asm xchg eax, edx end;
end;
procedure SwapXOR;
var i:Integer;
begin for i:=0 to 100-1 do asm
xor eax, edx
xor edx, eax
xor eax, edx
end;
end;
function RDTSC:Integer;
asm RDTSC
end;
var cXCHG,cXOR,c0,c1,i,j:Integer;
var a,b:Integer;
begin
a:=1; b:=2; cXCHG:=0;cXOR:=0;
c0:=RDTSC;
for j:=0 to 9 do begin
SwapXCHG; c1:=RDTSC;inc(cXCHG,c1-c0);c0:=c1;
SwapXOR; c1:=RDTSC;inc(cXOR,c1-c0);c0:=c1;
end;
Memo1.Lines.Add(Format('XOR=%5d XCHG=%5d',[cXOR,cXCHG]));
end;
これでも 結果は XOR= 3589 XCHG= 3631 でAthronでは同じって結論でいいんじゃないの
上と同じコードをx86-Famiky6と表示されるパソコンで走らせたら XOR= 4044 XCHG= 3756 って事で、若干 XCHG 命令が速いね。 まあ当然の結果だけど。
あと XOR の応用例 abs(x) を CDQ /XOR /SUB で書けるように max(a,b) を書くのに分岐無しで書くのに応用出来る
>>157 何を言っているのかわからないんだけど・・・。
> xorやmovによる交換も実質レジスタリネーミングされると
> 考えればパイプラインストールはほぼ発生してないはず。
そうなの??
mov はわからんでもないけど、xor が?
> xchg単体は mov/xor単体よりもずっと遅い
> という結果が出てくる。
単体で比較して何か意味あるの?
mov や xor に xchg 相当の事をやらせて初めて比較の意味があるんだけど。
164 :
デフォルトの名無しさん :02/12/31 01:33
age アセンブラの話よりも、本格的にトリッキーなコードキボンヌ
165 :
デフォルトの名無しさん :02/12/31 04:04
トレッキーなコードなら書きますが、それが何か?
int main(void){ printf("VOYAGER マンセー\n"); return 0; }
#define is_kanji1st(c) ((unsigned int) (c ^ 0x20) - 0xa1 < 0x3c) シフトJISの1バイト目か判定(コピペ 外出だったらスマソ。 新年もトリッキーなコードが飛び交いますよう
168 :
デフォルトの名無しさん :02/12/31 19:26
__machine { 0x05, 0x0000ffff ;add eax, 0000ffff } 機械語直打ちキター
>>168 大晦日に萎えるソースコード持ってくるな・・・
前スレ嫁、そして初日の出を見ることなく氏ね
__machine { 0xff, 0xf1 ;push ecx 0xe8, 0x40229833 ;call 40229833 } (´∀`)あはは
__machine { 0x90 } ( ゚∀゚ )あっひゃっひゃっひゃ
>>167 それは前スレで外出だったと思う。
どこからのコピペ?
>>173 NIFTYのどこかだと思ってたけど、元はFCだったか。
>>167 マシン語の世界ではごくごく普通に使ってた計算式であり、
アルゴリズムなんだけど、高級言語に浸かってくると
やっぱり忘れてしまうわな、そういうの…。
#CMP一発で5分岐するとかって、あったなぁ。
>175 別にマシン語の世界じゃなくたって、一般的では。 境界線は自前で書いてるか、ライブラリ使ってるか、じゃないの?
それがトリッキーじゃないって事は、こういうのもトリッキーじゃないのか。 大小によって -1,0,1を返す関数 type TValueSign = -1..1; function CompSign(A,B:Integer):TValueSign; asm CMP EAX,EDX; //A-B SETGE CL ADD CL,CL DEC CL CMP EAX,EDX; //A-B SETZ AL DEC AL AND AL,CL CBW CWDE end;
VC6がそんなコードを吐いた気がする。
179 :
デフォルトの名無しさん :03/01/05 05:51
#include <iostream> void SwapXCHG(int& a, int& b) { asm { mov eax, [a] mov ebx, [b] xchg eax, ebx mov [a], eax mov [b], ebx } } void SwapXOR(int& a, int& b) { asm { mov eax, [a] mov ebx, [b] xor eax, ebx xor ebx, eax xor eax, ebx mov [a], eax mov [b], ebx } }
int RDTSC() { int i; asm { RDTSC mov [i], eax } return i; } int main() { int a = 1, b = 2; int c0, c1, cXCHG = 0, cXOR = 0; for (int j = 0; j < 10; j++) { c0 = RDTSC(); for (int i = 0; i < 1000; i++) SwapXCHG(a, b); c1 = RDTSC(); cXCHG += c1 - c0; c0 = RDTSC(); for (int i = 0; i < 1000; i++) SwapXOR(a, b); c1 = RDTSC(); cXOR += c1 - c0; } std::cout << "XCHG = " << cXCHG << std::endl; std::cout << "XOR = " << cXOR << std::endl; }
>>179 ,180は
>>160 のソースをC++にしたものだが、Pen4で実行してみた限りでは
両者の関数のクロック数にほとんど差がない。
>>177 の比較関数もC++化して実行してみたが、単純なif文の方が約40%ほど
速かった。アセンブラによるトリッキーな書き方にはクロックの上でのアドバン
テージはないのだろうか。
>>181 比較の場合はランダムデータですか?
最近のCPUは分岐予測が余程優れているのかな…。
>>182 ランダムデータではないです。変数に値を入れておいて比較しました。
こんな感じ。
int main()
{
int c0, c1, cSETCC = 0, cIF = 0;
int a = 1, b = 2;
for (int j = 0; j < 10; j++) {
c0 = RDTSC();
for (int i = 0; i < 1000; i++) {
cmp1(a, b);
cmp1(b, a);
cmp1(a, a);
}
c1 = RDTSC();
cSETCC += c1 - c0;
c0 = RDTSC();
for (int i = 0; i < 1000; i++) {
cmp2(a, b);
cmp2(b, a);
cmp2(a, a);
}
c1 = RDTSC();
cIF += c1 - c0;
}
std::cout << "setcc = " << cSETCC << std::endl;
std::cout << "if = " << cIF << std::endl;
}
あらら、ランダムデータにしたら、setccの方が30%ほど速くなりました。 分岐予測が働きにくくなるからでしょうね。
ランダムデータとソート済みデータで速度が変わるんだねえ どれらいのランダムネス(?)が境界になるのか知りたいところ
>>185 P4だと、40個毎に乱数の系列を戻した時にほぼ同じタイムになるみたい。
const int N = 1000;
int cmp1(int& a, int& b)
{
int i;
asm {
MOV EAX,[a]
MOV EBX,[b]
CMP EAX,EBX; //A-B
SETGE CL
ADD CL,CL
DEC CL
CMP EAX,EBX; //A-B
SETZ AL
DEC AL
AND AL,CL
CBW
CWDE
MOV [i],EAX
}
return i;
}
int cmp2(int& a, int& b)
{
if (a < b) return -1;
else if (a > b) return 1;
return 0;
}
int RDTSC() { int i; asm { RDTSC mov [i], eax } return i; } int main() { int c0, c1, cSETCC = 0, cIF = 0; int a[N], b[N]; for (int i = 0; i < N; i++) { a[i] = std::rand(); // ここで比較用データをセットする b[i] = std::rand(); // if (i % 40 == 0) std::srand(0); // 乱数系列初期化用 }
for (int j = 0; j < 10; j++) { c0 = RDTSC(); for (int i = 0; i < 1000; i++) cmp1(a[i], b[i]); c1 = RDTSC(); cSETCC += c1 - c0; c0 = RDTSC(); for (int i = 0; i < 1000; i++) cmp2(a[i], b[i]); c1 = RDTSC(); cIF += c1 - c0; } std::cout << "setcc = " << cSETCC << std::endl; std::cout << "if = " << cIF << std::endl; } 長文スマソ
いや、勉強になった。 少し前まで、分岐予測ミスのペナルティは大きくて 分岐なしが平均的には余程速かったのになあ
グッジョブ! しかしこの比率ってCPUの世代で変わったりするのかな・・・
>>189 分岐履歴バッファがCPU内部にはあって、何重もの入れ子になった
ループの分岐を予測できるらしいですね。
P4のような深いパイプラインを持つCPUでは不可欠の機構なので
相当念入りに作ってあるようです。
P3やAthlonの結果も知りたいのですが、どなたか試してみていただ
けませんか?
AthlonXP1800+、VC++6にてテストしてみた。 概ねcmp1のほうが速いですが、評価順や最適化の有り無しでも 結果が変わるようです。(i % 40)の部分はほぼ影響なかった。 正確に測るには関数内に_asmでRDTSC入れてDWORD境界の 対策をしないと駄目かも知れず。 あ、最適化するとcmp2(if 〜 else if 〜)の関数内にあるジャンプ 命令は1個ですたw
あ、DWORD境界ってのはRDTSCの返り値がループした時の事です。
cmp1ってローカル変数に代入するから こんな小さなコードだと少しはロスがあると思うわけ。 (フルアセンブラや、gccやbccのようにレジスタを直接返せれば別だけど) ってゆーかさ、"トリッキーなコード"を名乗るんだったら、 せめてこの程度までは最適化してから比較しようよ。 と言ったものの、あまり詳しくないんで、 見た目が最適化されただけで、内部的なクロック数は増えてるしれない。 int cmp1(int a, int b) { asm { mov eax, a // 引数をレジスタ渡しだと・・・ cmp eax, b // setl al setg cl neg al xor al, cl cbw cwde mov a, eax // <-これがじゃま } return a; }
>>194 SETxx はフラグに影響を与えなかったっけ?
SETccはフラグに影響しない(マニュアルに書いてある)
コンパイラはフラグを「比較直後」以外に使うのがうまくないんだよね。
その後で並べ替えることはあっても。
だから、アセンブラレベルでなら、add/subの代わりにleaを用いてフラグを維持し、
それから条件を調べる(jmp等)って方法なんかもでてくるわけさ。
もちろん、よほどクリティカルな部分でない限り、意味は無いけどね。
よく考えたら、
>>194 はxorではなくorを使ってもいいんだけど、
xorの方が意味が分かりにくい==トリッキーってことで許して。
で、ほぼ同じロジックでCで書くとしたら
int cmp2(int a, int b)
{
return (a < b) | -(a > b);
}
だね。
そうか。intelから資料ダウンロードして確認したよ。 持ってた本に実行後にフラグが変更されてるような用例載ってたから勘違いしてた。 じゃあ1ステップ短く出来るよ type TValueSign = -1..1; function CompSign(A,B:Integer):TValueSign; asm CMP EAX,EDX; //A-B SETLE AH SETGE AL SUB AL,AH CBW CWDE end;
せっかくいい感じにベンチマークできてたのに 194から急に厨臭くなった・・・
cbw+cwdeとmovsxはどっちがいいのかな?
と
>>197 を読んで思い出したけど、
似たようなロジックは半年くらい前にC言語スレで見た(書いた)気がする。
減算結果の最上位bitをシフトしてxorとるやつ。
とここまで書いて、その時見たのは「aとbの符号が一致しているかを返す」
だったのを思い出した。
そういうのがあったからxor使っちゃったんだな(もちろん、subの方が良いけど)
>>198 ん?ベンチマーク続けてかまわないんじゃないの?
一つのスレッドで複数の話題が進行するなんてよくあることだし。
要は、分岐予測があたることに期待した単純なコードと
分岐予測がはずれる可能性に備えて少し複雑なコードで
CPUやデータのばらつきによって、どちらが良いか、どのあたりが分岐点になるのかでしょ?
実際、現在のCPUでは分岐予測ミスやメモリアクセスなどの
ペナルティを減らす方がはるかに重要だし。
いや、急に見た目最適化とかステップ数とか そういうのが当てにならないにもかかわらず アナクロな方向になってあきれただけ
一つの命令自体のクロック数はあまり意味はないけど、 ・メモリアクセスがない ・分岐がない ・複雑な命令がない ・依存関係のある命令が少ない 場合ならば、充分意味があるよ。 少なくとも俺は、 「両方Cで書いて分岐の有無によるテスト」か 「両方アセンブラで書いて分岐の有無によるテスト」 にしないなら、 「片方をC、片方をアセンブラで書いてどちらも分岐命令を使う」 「片方をC、片方をアセンブラで書いてどちらも分岐命令を使わない」 でなければ、あまり意味はないと思っているけどね。 出来れば、全てアセンブラでアラインも揃え、 分岐の有無による差を見たいけどね。
> 場合ならば、充分意味があるよ。 単なる思い込みコードをベンチマーク結果なしにみせつけられてもねえ。
そうだね。 このスレに書く"トリッキーなコード"はベンチマークがなきゃ意味無いよね。
速度のためのトリックならベンチマーク必須だね。 コード量削減のためならバイト数の計測。 他人を驚かすのが目的なら・・・どうしよう
>cbw+cwdeとmovsxはどっちがいいのかな? あ! 忘れてた。 MOVSX があったんだ。 そりゃMOVSX1命令の方が短いでしょ type TValueSign = -1..1; function CompSign(A,B:Integer):TValueSign; asm CMP EAX,EDX; //A-B SETLE AH SETGE AL SUB AL,AH MOVSX AX,AL end;
どーーーしても「コードを見れば明らか」と納得できない人約一名がいるみたいなので
ベンチマーク取りましたよ。
test1が
>>183 の外ループを10倍したもの
test2が
>>187-188 の外ループを10倍したもの
cmp1が
>>197 の前後にロードとストアを入れたもの
cmp2が
>>186 のcmp1の引数を参照にしなかったもの
呼び出し規約はcdeclで。
test1
cmp1 = 4943201
cmp2 = 7133229
test2
cmp1 = 1677185
cmp2 = 2230045
ま、こんなもんでしょ。
ロード/ストア/スタックフレーム操作/callが入るからそうそう極端な差はつかないね。
あ、アーキテクチャはP6ね
おう、厨房から脱出した人、おめでとう
安心しろ。 「明らか」な結果をわざわざ測定するのは今回だけ。学生実験とは違うから。 まあ雪で出かけられない中、良い暇つぶしになったよ。
結果が明らか? んなアホな
>>186 より
>>197 や
>>206 が速いのは(わかる人にとっては)明らかだよ。
もちろん、何十年後かのアーキテクチャでもそうだとは言い切らないけど、
今後10年の間は明らか。
逆転するようなことがあっても、その時代にはx86(IA-32)は寿命を終えている。
明らかな理由は
>>202 の前半に書いたけど、理解できなかったんだろうね。
うーん、厨房は死んでも直らないとはこのことか・・・ 残念。
215 :
デフォルトの名無しさん :03/01/05 22:25
おもしろいからあげ
うん、俺はベンチマークも提示できないような厨房だから 煽りにも精一杯反応しちゃうよ。 ねー、ぼくちゃんは厨房じゃないんでしょ? 煽りに反応しちゃだめでしょ。
腐ってきた。194と197どっちが腐らせたんだ。
この程度で煽りと思ってしまうのはまずいと思う。 単なる指摘でしょう。 そういやIA-32って今年で18周年だね。
>198 >201 >203 >205 >209 >211 >214
なるほど、いきなり厨臭くなったことを指摘してくれたんだね。どうもありがとう。
非常に重要な指摘でした 有意義な時間を過ごせました
そうだ、
>>198 さんは
俺が
>>202 の後半で指摘した「ベンチマークは測定条件を揃えて」ってのは
放置しちゃったのかな?
>>198 で、すごくベンチマークが楽しみそうだったのに。
まあ、測定条件を揃えずに、単に「分岐予測による効果で結果が変わる」ことだけなら
>>188 まででわかったんだから
AthlonもP3も関係ないし、どちらが何%速いとか
どこで逆転するとかの報告は必要ないな。
確かに、アセンブラの方を最適化したから厨房臭かったかもね。
むしろ、「これ↓の結果を比較しろ」と書いた方が良かったか?
int cmp1(int a, int b) {
return (a > b) - (a < b);
}
int cmp2(int a, int b){
if (a < b) return -1;
else if (a > b) return 1;
return 0;
}
最後に付け加えとこ。
>>177 (以降)はSETccを使って分岐をなくしているけど、
CMOVでも同じ結果が出てる。
少なくとも、現存のx86アーキテクチャは
分岐予測成功 > CMOV >>> 分岐予測失敗
になってる。
>少なくとも、現存のx86アーキテクチャは > 分岐予測成功 > CMOV >>> 分岐予測失敗 >になってる。 P3からP4になって、さらに強まった気がするんだけどどうかなあ
俺には難しいけどいいスレっぽいな。 がんばれ!
へえ CMOV か Pen2以後で使えるんだね。
なるほど、
>>206 さんのようにすると、ランダムな比較をしても速いね。
ステップ数が少ないので、if文では完全な規則性のある数を比較した場合
以外ほとんどかなわない。
CMOVを使ったプログラムでも検証してみます。
なるほど、CMOVccでもSETccと同等の速度が出るね。CMOVがイミディエート値 をロードできると思ってたけど、だめなのね。 int cmp1(int& a, int& b) { static int one = 1, mone = -1; int i; asm { MOV ESI,a MOV EDI,b MOV EAX,0 CMP ESI,EDI; CMOVL EAX,mone CMOVG EAX,one MOV i,EAX } return i; }
>>228 CMP じゃなlくて SUB にすれば 引算結果のゼロを使えるから1ステップ短くなるよ
デバッガで追いかけたら、次の部分が正しいコードに展開されてなかった。 MOV ESI,a MOV EDI,b int&a, int& bとなっているので、aとbはポインタを与えてしまう。だからこれは MOV ESI,a MOV ESI,[ESI] MOV EDI,b MOV EDI,[EDI] と書かなければならない。このような不都合を避けるため、intの参照ではなく 値で渡す事にした。if文の方も値で渡すようにしたのだが、意外とif文が速くなっ た。乱数の発生系列の初期化を70個毎にしないとCMOVccやSETccが負けて しまう。
>>229 それはなかなかトリッキーですね!早速やってみます!
>>229 このようにしてみました。規則的なifの速度にはかなわないけど、不規則な
ifに対しては、乱数の初期化を10個毎にしても勝てます!(Pentium4)
asm {
MOV EAX,a
MOV EBX,b
SUB EAX,EBX;
CMOVL EAX,mone
CMOVG EAX,one
MOV i,EAX
}
あんまり短いコードでベンチマークしても意味がないと思うけどなあ 分岐なしに書けるなら、多少冗長に見えても、使った方が全体のパフォーマンスが上がる事がおおいよ。 年々大きくはなっても、分岐ターゲット・バッファ(BTB)はやっぱり有限だからさ。
>>233 大規模なプログラムだと、分岐の過程は一般的にランダムだから、分岐フロー
を無くすようなプログラムが効果的でしょうね。ただ、短いコードでないと、分岐
無しで動作するようなプログラムを書く事は非常に難しいでしょうけど。
>>234 いやそうじゃなくて、再利用度の高い一部の関数とかを分岐無しが可能なら、出来る時に書いておけば
全体のパフォーマンスが上がるだろうって事。
たとえ、その関数だけ評価して if 文よりパフォーマンスが悪くても、
もちろん重い処理の内側のループを書くような場合は別だけどさ
>>235 ああなるほど、BTBをなるべく消費しない関数が書けるなら書いておこうって
事ですね。納得。その分別の箇所でBTBが有効活用できるって事か。
SSE2命令を使ったトリッキーなプログラムってありますか?
大規模なプログラムでそんなこと気にする人っているんかいな
SE を使ったトリッキーなプログラムってありますか?
>>232 キャッシュにヒットしないと遅い予感
って、そんな場合は、ほとんど意味が無いから置いといて
Pen4はCMOVccのレイテンシがマニュアルに見当たらないので
知らなかったけど結構早かったんですね…
でも、おそらくP6系ではSETccの方が早いはずので
P6系を持ってる方はレッツチャレンジ♪
(と言っても、あまり差は出ないと思うけど…)
ついでに両方の値をレジスタに入れる必要は…
asm {
MOV EAX,a
SUB EAX,b
CMOVL EAX,mone
:
}
>>239 SEにプログラム作らせる事自体がトリッキー
242 :
デフォルトの名無しさん :03/01/08 17:23
なんかみんなスゲー。仕事でプログラムやってる人?? 年齢もしりたいw
いつの間にか前スレが埋められてる・・・ 2年間、もってくれるかなと思ってたけど、 それまでに落ちちゃうかなぁ。
IP記録実験
http://qb.2ch.net/test/read.cgi/accuse/1042013605/ 1 名前:ひろゆき ◆3SHRUNYAXA @どうやら管理人 ★ 投稿日:03/01/08 17:13 ID:???
そんなわけで、qbサーバでIPの記録実験をはじめましたー。
27 名前:心得をよく読みましょう 投稿日:03/01/08 17:20 ID:yL/kYdMc
SETTING.TXT管轄でないということは全鯖導入を視野に、か?
38 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/08 17:22 ID:rLfxQ17l
>>27 鋭いです。
73 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/08 17:27 ID:rLfxQ17l
>ところで、IPが抜かれて何か今までと変わることってあるのでしょうか?
・今までより、サーバが重くなる。
・裁判所や警察からの照会があった場合にはIPを提出することがある。
245 :
デフォルトの名無しさん :03/01/08 23:38
age
全レスです。
あこがれのヒモ生活のためにがんばってもらいたいものです。
>>10
>>212 llllllllllll lllll
lllllll lllll
lllll llllll
lllll llllllllll llllllllll lllll
lllll lllll llllllllll lllllllllllllllllllllllllllllllllll lllllll
lllll llllllllll llllllllll lllllllllllllll lllll
llllllllll llllllllll llllllllll lllll lllll lllllllll
llllllllll lllll llllllll
∧_∧ ∧_∧ ∧_∧ ∧_∧
( ´_ゝ`) ( ´_ゝ`) ( ´_ゝ`) ( ´_ゝ`)
∧_∧ ) ∧_∧ )∧_∧ )∧_∧ )
( ´_ゝ`) ( ´_ゝ`) ( ´_ゝ`) ( ´_ゝ`)
∧_∧ ) ∧_∧ ) ∧_∧ )∧_∧ )
( ´_ゝ`) ( ´_ゝ`) ( ´_ゝ`) ( ´_ゝ`)/|
(____) (____) (____) (____)
/ ./|./ /|./ /|/ /|
| ̄ ̄ ̄|/| ̄ ̄ ̄|/| ̄ ̄ ̄|/| ̄ ̄ ̄|/|
|| ̄ ̄ ̄|| || ̄ ̄ ̄|| || ̄ ̄ ̄|| || ̄ ̄ ̄||
無限にログを残してるサーバ管理者っていないと思います。
俺のプロバ当ててみろ!!!!!!!!
もう2ちゃんねるも終わりです。 ほかのところいこーぜ
>>158 IPとられるとられないにかかわらず、重大な決意で告発する人はいると思うけど。
そういうひとが保護されるかどうかが問題だわなー。
ウソ書いてひとに迷惑かける奴は保護される価値がないと思うけれども。
匿名とは、自分が提示する情報だけで勝負することをいうので、
======2==C==H======================================================
2ちゃんねるのお勧めな話題と
ネットでの面白い出来事を配送したいと思ってます。。。
===============================読者数: 138720人 発行日:2003/1/9
年末年始ボケがそろそろ収まり始めた今日このごろのひろゆきです。
そんなわけで、年末に予告したIP記録ですが実験を開始しています。
「2ちゃんねる20030107」
こんな感じで各掲示板の最下部に日付が入ってるんですが、
20030107以降になってるところはログ記録実験中ですー。
んじゃ!
────────────────────────Age2ch─
■この書き込みは、Age2chを使って配信されています。
────────────────────────────
Keep your thread alive !
http://pc3.2ch.net/test/read.cgi/software/1041952901/l50 ────────────────────────────
記念かきこ
あめぞうという昔旺盛を極めた掲示板は「誹謗・中傷・アダルトお断り」の文字を書き込んだ 事が原因の1つとなって潰れたが、いまの2chは「誹謗・中傷・密告お断り」というのを出したのと 同じ事なんだよなあ、、、
>訴状と内容証明の区別ができてる? 訴状だろうと内容証明だろうと、 問題は「掲示板に名誉毀損が書いてあると知りえた時点で、 削除する義務がある」ってことなんじゃないすか?
挙手による多数決は最大の愚行!! 匿名性が失われ自分に反対する者が誰かは わかるのに小数派には反論さえ許されない 最悪のシステム!! もしも常に特定の人物と 意見が対立し 常に片方だけが意思を 抹殺されたら… それが続けば必ず集団は決裂する!!
じゃ、winnyでニュー速のスレ立てるか?
鳥カエレ!は今まで言ったこともあるが 女子大生カエレ!は心情的に言いにくいじゃないのぅ! (`ε´)プー
荒しのヤシは別に困らないだろ? それよりも貴重な情報が流れなくなる気が、、、 ネタでした と言ってほしいぃ
2chのIDてIPを変換してるんだっけ? だったら、全板強制IDにして暗号キーだけ保存しておけばいいんじゃないの?
終わったな ま、ひろゆきは何も悪いことはしないわけだが
ボルタレンじゃなくて??
誰か IDにIPを出すことを要求します ってスレ立てておながい
∧_∧ / ̄ ̄ ̄ ̄ ̄ ( ´∀`) < なんでだろ〜! ⊂⌒ て) \_____ ( 、___つ ) ) し' ∧_∧ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ( ´∀` ) < なんでだろ〜♪ / ̄ヽ/,― 、\ o。。。\_______ | ||三∪●)三mΕ∃. \_,へ--イ | ゚ ゚ ゚ (_)(_)
======2==C==H======================================================
2ちゃんねるのお勧めな話題と
ネットでの面白い出来事を配送したいと思ってます。。。
===============================読者数: 139038人 発行日:2003/1/10
なにやら、連日メルマガだしてるひろゆきです。
そんなわけで、ログ記録実験ですが、いちいちサーバ指定するのが面倒なので、
全部のサーバに入れてみました。
重くなって落ちたりしてもご愛嬌ってことで。。。
んじゃ!
────────────────────────Age2ch─
■この書き込みは、Age2chを使って配信されています。
────────────────────────────
Keep your thread alive !
http://pc3.2ch.net/test/read.cgi/software/1041952901/l50 ────────────────────────────
変なことって例えば?
明日もそれ以降も何もしません
そんなことをしようとするより 鯖をクラックするだろう
矩形の問題はどうなったのか気になったり気にならなかったり
まぁなんだ 「ひろゆきよ ラウンジが重いんだが・・・と電話しまくって即閉鎖」 が一番早そうだな(藁
2chで内部告発的な事をするリスクが大きくなるのかな? 発信元がわかるんで、告発された側が「よーし金でねじ伏せちゃうぞー」 とか言って裁判でも起こしまくって。 そんな状況はガクブルだから、面白そうな(真実である事が前提の)投稿は、減る?のかな? 考え過ぎ?って言うか見当違い?どうだ?どうなんだ?
,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,--―'''""`ヽ'  ̄`ヽ、 / ヾ / ~`ヽ / ヽ;:/""""ヾ ミ ヽ / ;:;;:::''''"""" \ i / / ヽ ヾヽ / / / ;/ ヾ ヽ / ;:;:ヽ ,,,,;;::'''''ヽ ;:| i / ,,,,;;::::::::::::::: ヽ ヽ | | | " :::: /\ ヾ ヽ | | ヾ | /\ ::::::. : | ;:| | ;:| : ::::::: : .、 | :| | ヽ ( ,--、 ,:"' | /|! | ヽ ヾ |;:/ | | __,-'ニニニヽ /| || `、ヽ ヾニ二ン" /;:| | ヽ \ /ノ | i `ー-::、_ ,,..-'|ヽ ヽ;:;:;:;: ;:人 `ー――'''''"~ / ヽ \;:;:;:;:/ `ー-、 ,.-'" \ー-、 ,.-'" :/ \ ,.-''" | / ! ~>、,.-''" | ,,..-‐'''"" ヾ ,.-''"――――-、 / (^^)は山崎渉であると見抜ける人でないと (掲示板を使うのは)難しい(^^)
あと約1500
バガンっっ!!!!!ズサッ ガッ ギュィィ ゴッググモッッ雨雨 グモッチュチュイチュイチュイーーーーーーーーーーーーーーーーーーーんチュイチュイチュイチュイ――ン 罵ッゴんばっこんばっ婆ッゴんばぎゅブギュ罵ぎゅぎゅきゅ ぼごんぼごんぼごんぼごん 跋扈ン跋扈ン跋扈ンバッカンバッカン馬鹿馬鹿婆きゅうううーー ギュ気ギュ気ギュ気いい疑義一ギいいっ ギュぎゅうぎゅううう ぶじゅぶじゅぶじゅ ききっーーぃ きい ゴットン となって、ミンチ轢肉になって成仏してしまったそうです。 尚、貨物はフルパワー・全快で走行していた長い編成だったので、凄まじい勢い で轢断・繊断(物性物理学の運動エネルギー・車輪とレールの轢断機により)され 15歳の中3は、肉片と化したそうです。 お気の毒ですが、この肉片は荼毘に附して、灰にし、土に帰します。あしからず ご了承くだされい。
ああ、昨日のあったやつか。一応乗ったんだね
そうだね。 今なら勝つ確率高いしね。 しかも何百ももらえるしw
>59K+TtJ+ ややこしいからそのトリップ使うな。 今回の裁判の話と今後起こりうる訴訟は全然別の話になるだろうから、 (プロバイダ責任制限法と削除システムの変更がある) ごっちゃにして話をするのは無意味。
今後sports3鯖は定期的にhtml化されるの?
(^^)
4nd にびっくりすますた。
多数決 (a|b)^(a|c)^(b|c)
(^^)
292 :
デフォルトの名無しさん :03/01/19 10:59
age アセンブラネタきぼん。実験しますので
今更だが、
>>132 をやってみました。
Pentium4 2.53GHz + DDRSDRAM(PC2100)
func1 = 1286
func2 = 1286
func3 = 1287
func4 = 2568
mov, xor, xchg はほとんど差がありませんでした。Pentium3とは
傾向が違うようです。
>>293 #define LOOP 500000
を
#define LOOP 50000000
でキボンヌ。
>>294 どうぞ。
func1 = 128540
func2 = 128966
func3 = 128906
func4 = 306264
僅差で mov > xchg > xor >>>> pop でつか。 誤差はあるかも知れないけど・・・。 P3 では xchg > mov >> xor >>>> pop だった気がする。
誤差だろ。
じゃあ #define LOOP 4000000000 でキボンヌ。
>>298 どぞ。
push/popだけ異常に遅いですな。
func1 = 10361072
func2 = 10327317
func3 = 10335487
func4 = 27160516
xor が速いように見えるな。
>>293-300 長時間かかるとOSのタイムスライスなども気になるので
LOOP回数はそれほど長くないほうがいい。
PerfomanceCounterの制度は十分に高かったはず。。。
func1 = func2 = func3 > func4
と考えて
mov*3 = xor*3 = xchg*1 = (push*2/pop*2)*2
かな?
ちなみに最初は dec ecx & jnz の代わりに loop を
使ってみたんだが loop はかなり遅かった…。びっくり。
Athlon系やCrusoe系の結果も興味あるところ…。
>>301 Pentium4はALUがPentium3と違うアーキテクチャのようだし、
トレースキャッシュとかいうよく分からない機構を使っていたりで、
単純ループには強いみたい。
loop命令使って書いてみましょうか。そしたらmovのセクションを
dec & jnz と loopにしたものとで比較。
そう言えばOSはWindowsXP使ってます。push/popのようなメモリアクセス が発生する命令はOSの影響があって遅くなると聞いたことがあるのです が本当でしょうか?
func1がdec & jnz で、func11がloop命令を使いました。 確かに遅いですね。 func1 = 1354 func11 = 1927 何かこのスレトリッキーなコードでなくてアセンブラの最適化スレ 見たいになってきたね(w
>>303 push/popなどのスタックをアクセスする命令は、
スタックセグメント経由で行われるため、OSの設定によっては
遅くなる可能性がある。
嘘だけど。
>>305 WindowsNTの古いバージョンでは、スタックアクセスが発生すると
いちいち割り込みがかかってすごく遅くなってたようですよ。
WindowsXPもNT系なので、push/popの速度が95系とは違うのではない
かと思ったのです。でもPentium4でMeとか使ってる人はさすがに少ない
だろうな。
スタックが伸びるときに例外出すのは分かるけど、 一度ページインしたら関係ないような・・・古いって3以前?
Pen4では、レジスタの入れ替えにpush/popは使わず、 それ以外を使え、ってことですね。 ベンチマークするといろいろ分かって面白い。
>>307 NT2だったかも。それでCALL命令とかも異常に遅くて、NT3で直された
というような話をどこかで聞いた。
>>308 Athlonではどうなんでしょう?かなり優れたアーキテクチャらしいけど。
Pen4はALUが倍速動作しているので、メモリアクセスがないと強いみたい。
push/popってメモリに反映させる必要があるだろうから、 メモリ/キャッシュのインターフェースが異常に賢くないかぎり 同じぐらいの結果じゃないの。 NT2か・・・ネタにしては陳腐だったな。
NT2 ってなんですか?
(^^)
315 :
デフォルトの名無しさん :03/01/31 02:25
>>106 から引きずってる話題だが、肝心なこと忘れてないか?
XOR は両辺が同値だったら 0 になってしまうぞ。
そのチェックはどうするんだ?
>>316 「から引きずってる」 って書いたんだから、それより後ろも読んでくれよ・・・。
要約すると、2 つのレジスタの値を交換するには何が最も速いかという話。
候補としては、
1. 別のレジスタを介して MOV で交換。
2. XOR A, B、XOR B, A、XOR A, B で交換。
3. XCHG で交換。
4. スタックを介して POP と PUSH で交換。
で、スタックを使う 4 は論外に遅く、他は CPU 等によって変動するが
僅差という結論だった。
んでもって、2 の XOR は実は問題あるんじゃないかと 315 に書いたの。
>>316 ネタでしょ
アセンブラ(じゃなくても良いけど)でeaxとebxの値を入れかえる時に
↓のようにしてeaxとebxの値を入れかえる
xor eax, ebx; eax = (eax^ebx)
xor ebx, eax; ebx = ebx^(eax^ebx) → eax^ebx^ebx → eax^0 → eax
xor eax, ebx; eax = (eax^ebx)^eax → eax^eax^ebx → 0^ebx → ebx
この時eaxとebxが同じ値だと一度0になってしまうので
>>315 の主張が正しいように見えるが、それに同意すると
最終的には、↓のように問題無く入れ替わる事を指摘される罠
xor eax, ebx; eax = 0
xor ebx, eax; ebx = ebx^0 → ebx(=eax)
xor eax, ebx; eax = 0^ebx → ebx(=eax)
xchgがmov・xor三回とほぼ同じというのは 内部で三命令に分解されちゃってるということなんでしょーか。
>>317 C言語でスワップを XOR で書くとまずいを引きずってるのかな。
あれは同じ値ではなくて同じアドレスの時まずいってやつだから。
>>320 P6以降は内部でMicroコードに分解されているので有り得るかもしれませんね。
void putbar(int n) { int k; for( k=0; k<n; ++k ) putchar( "****|"[k%5] ); putchar('\n'); }
「読みにくい」 と 「トリッキー」 を勘違いすることなかれ
putbar()って何? "****|"の文字の並びに何か意味があるの?
putbar(13) ****|****|*** というように5文字ごとに|を入れたいってことだろう。
putchar((k % 5)["****|"]);
328 :
デフォルトの名無しさん :03/02/13 16:55
ほしゅ〜
329 :
デフォルトの名無しさん :03/02/13 17:17
330 :
デフォルトの名無しさん :03/02/18 02:41
VBだけど Dim buf As String * 260 hoge=Left$(buf, GetWindowsDirectory(buf, 260))
>>330 どこがトリッキーなのかわからん。解説希望。
ぬるっぽーなコードきぼん
>>331 bufの値が空白に見えるうちにLeft関数に渡すところじゃない?
ついでにGetWindowsDirectoryが取得した文字数を返すから不要なスペースを除去できる。
(ディレクトリ名に2バイト文字が入ると破綻しそうな気もするけど)
Cだとごく普通のコードだな。
昔BASICでよく使った手法思い出した。 RIGHT$("00"+HEX$(n),2) Cのsprintf(s,"%02X",n)相当。
>>335 RIGHT$(HEX$(256+n),2)
こっちが少しだけトリッキーかも 速度も速いし
どーせなら足し算じゃなく論理和で RIGHT$(HEX$(256 OR n),2)
http://www.emit.jp/prog/prog.html のところに、4byteまとめて平均値を出す方法が
> unsigned long v0, v1, v2;
> // v0, v1 にはキャストするなり、あらかじめデータを入れておく
> v2 = (v0 & v1) + (((v0 ^ v1) & 0xfefefefe) >> 1);
のようにのっているんだけど…
どうしてこうなるの?
がんばっても理解できないので
解説してほしいのですが…
加算をbit単位で考えてみれば自ずと理解出来るかと
>>339 最初の v0 & v1 は、足したらケタがあがるところで、
次の v0 ^ v1 は、足すところで、
次の & と >> は半分にするところでしょうか?
なんで
( ((v0 & v1) + (v0 ^ v1)) & 0xfefefefe ) >> 1
ではないの?
(v0 & v1) の方は1bit繰り上がりがあるから。
なんとなくわかってきた気がします。 どうもありがとうございました。
>>338 現在のCPUが、どうやって加減算をしてるか勉強すれば
一発で理解出来るようになるよ
#define cat(a, b) a##b #define rem cat(/, /) はがいしゅつですか?
プリプロセスの結果としてできたコメントってプリプロセッサは削除するんだっけ?
…らしいね。
規格上求められる挙動なんだっけ、という意味でよろしこ。
348 :
デフォルトの名無しさん :03/03/10 13:27
>>344 前スレの138にて。意味違う(?)けど。
ってこれ副作用あるね・・・
あげちった(汗
##って引数以外に効果あったっけ?
ない。
期待あげ。2週間は痛い。
8085のdiv関数のコード逆アセンブル: CDxxxx call DIVIHD##;HL/DE-->DE=余り、HL=商 ; 除算を実行した直後は上位ワード=余り,下位ワード=商、が標準的手法。 C1 pop B ;リターンアドレス pop F1 pop PSW F1 pop PSW ;SPを返却値のアドレスまでpop D5 push D ;余りpush E5 push H ;商をpush C5 push B ;リターンアドレスpushでcall時点の状態 C9 ret ;リターンアドレスpop, 分岐 ; 1バイト命令だけでよく書けてると思います。んで、この結果を sprintf(wk,"・・・%d %d",div(int,10)で0.1単位の整数の編集に使い、 割り算を1回ですませた。3MのCPUでシビアな処理の所、ウマーでした。
>>353 シビアな処理でsprintfってあんた、、、
目の付け処がピンボケです。
#define QUESTION(bb) ((bb)||!(bb)) /* hamlet, shakespeare */
トリッキーではないがなw
気に入ったんで・・・汗 昔みたいに盛り上がらないかなぁ。
もう2周年超えたんだなsage
>>354 そんなにピンボケでもなかったのですよ。printfルールの文字列を
出力する仕事だったので、ASMで変に固定長の出力とかは不自然に見える。
10で割った商と余りを編集するのに、353のやり方を使わないと/で除算、
%でまた除算てことになるのですね。だからこれは当たりと思った手法です。
私もASMで商と余りを使う手法を考えたら結局これに行ったのです。
>>359 printfのコストを考えれば2度の割り算なんてないのと同じということだとおもわれ。
割り算1つ減らすよりもほかに最適化する方法はありそうだしな。
つーかね。 定数 10 による除算は、勝手に最適化されるぞ。
353の例では(LSI i8080 CG ver 3.4a Copyright (C) 1986-1994) 最適化はされませんでしたね。いちいちどんなASMコードが出るか見ながら c表現を手動最適化でした。sprintf系も「実数ハンドリング機能を省いた コンパクト版」というのが付いていてデフォールトはそちらを使うように なってました。
>>353 =362 は小手先の最適化で天狗になって全体を通しての
効率を見ることができないヤシってことでFA?
>>364 最適化なしコンパイラ。せいぜい前の命令で使ったレジスタ値を次で使う程度。
>>363 んじゃ全体を通しての効率の噺ね。ROM32K,RAM8K,3Mの8085A,8251が4CH
皆4.8K,8,1,N。1,2CHからバイナリ13バイトで位置・速度・移動方向等の情報が最大
60個ブロッキングされて3秒毎に送られてくる。それを3,4CHにASCII文字列にして
送信する。1個を編集した文字列は55バイト前後になる。旧systemはASM5K行位
あったが、有効レコードが30個あたりから出力が止まるから何とかしてくれと
いう問題でした。
ROMは余ってますが通信条件から、有効レコード28個あたりで出力時間が3秒になる のが判りますね。そのときもう次の入力が入って来るわけで、この事態に対し 旧systemは脆弱だったわけです。もともと6秒間隔で作って、後から勝手に 3秒間隔で使い始めたので、作った奴にバグだ直せと言えなかったようです。 実装RAM条件から、60個出力が2度続くように耐えられるだけ送信リングバッファ を確保できないことが判ります。皆さんならどう解決しますか? あ、割り算の話は、バイナリ値が0.1単位の整数表現だからです。
>>362 もういいよ。この話題あきたよ。読みにくいし。
lsr #5,d0 btst d0,#$90 Shift_JIS の1バイト目判別。 (0x80 とか 0xfd 以降にも機種依存文字が割り当てられてた環境だった)
>>370 何のアセンブラだか分からんので、Cで書いてくれない?
>>371 cはunsigned char
(1<<(c
>>5 ))&0x90
しかしこのコードの一番のポイントはbtst命令のオペランドなのだが…
>>372 「何のアセンブラだか分からん」 と言う人に、「ポイントはbtst命令」 と返すのは
いかがなものかと。
>>370 > (0x80 とか 0xfd 以降にも機種依存文字が割り当てられてた環境だった)
理由が苦しいな、、、
といいつつ、同じく0x80,0xFC-を無視していいときは
0xE0とtesttして、サインフラグとパリティ Oddを見てたよ。
結局のところ
>>370 と発想は同じかもしれん。
>>373 ごめん、、、でもうまく説明できない・・・
保守
377 :
デフォルトの名無しさん :03/04/15 23:05
最近HTTPリクエストが面白くて色々遊んでいるんだけれど、ちょっとお題を。 HTTP リクエストとブラウザ上の JavaScript のみを使って、 なにか適当な2つのブラウザ同士が通信する事って出来るかな? 俺の結論は「出来ない」なんだけれど…。 どうあがいてもブラウザで Listen 出来ないよね? 間に中継サーバを立てればもちろん出来るとは思うけど、どうでしょう?
>>377 ブラウザが JavaScript で Listen 出来ちゃったら
そのコード埋め込んであるページを開いた時点で・・・(((;゚Д゚))ガクガクブルブル
379 :
デフォルトの名無しさん :03/04/16 23:49
中継サーバを立てたら、すべてのデータが全部中継サーバ経由になるのかな?
380 :
デフォルトの名無しさん :03/04/16 23:52
>>377 Javaアプレット経由でできるかも。
通信用のアプレットを作って、staticな変数とかでやりとり...
ちょっとトリッキーだな。
381 :
デフォルトの名無しさん :03/04/17 00:41
>>380 具体的にアプレットを使ってどうやるんだ?
中継サーバなしでは無理だろう、たぶん。
中継サーバの負荷をどれだけ小さくできるか、という方がトリッキーっぽい
(^^)
383 :
デフォルトの名無しさん :03/04/17 17:06
HTTPを使ったP2P…不可能ぽ 間のサーバがあったところで、転送量を分散するシステムが必須だな
>>377 IEだったらセキュリティーホール突けば…
∧_∧ ( ^^ )< ぬるぽ(^^)
∧_∧ ( ^^ )< ぬるぽ(^^)
387 :
デフォルトの名無しさん :03/04/20 11:26
388 :
デフォルトの名無しさん :03/05/04 12:49
これはトリッキーかなぁ…。(ーー;) かなり前作った矩形同士の当たり判定ルーチン。(VisualC) [ ]が付いたり付かなかったりしてて気持ち悪い。(苦笑) __asm{ mov eax, left2; mov edi, top2; sub eax, [left1]; sub edi, [top1]; mov esi, [right1]; mov edx, [bottom1]; sub esi, right2; sub edx, bottom2; or eax, edi; or esi, edx; xor ebx, ebx; or eax, esi; setge bl;
389 :
388続き :03/05/04 12:49
mov eax, [left1]; shl ebx, 1; mov edi, left2; sub eax, right2; sub edi, [right1]; mov esi, [top1]; mov edx, top2; sub esi, bottom2; sub edx, [bottom1]; and edi, eax; and esi, edx; xor eax, eax; xor ecx, ecx; sub eax, ebx; and edi, esi; sets cl; sub eax, ecx; }
!(゜∀゜; なんか前スレに似たようなものが…!?(ガーソ!) よく見ておけばこんなクソコードを晒すこともなかったのにィ!(笑)
前スレの15がウザイ
誰かこれを解説してくれ。 /* invariant in modulo 1<<31 */ #define EXTEND32(x) (((1<<31)-1-(x))^~(~0<<31))
>>392 未定義。intが32ビットで2の補数表現のマシンでも動く保証はない。
どこが未定義?
ここ。 (1 << 31) - 1
その後の~(~0<<31)は大丈夫なの?
>>392 はintが32ビットよりも大きい場合のコードのようなんだけど、
それでも未定義?
つーか、このコードが意図してること分かる?
∧_∧ ピュ.ー ( ^^ ) <これからも僕を応援して下さいね(^^)。 =〔~∪ ̄ ̄〕 = ◎――◎ 山崎渉
400!
>400 もう2週間くらい粘ってほしかった
漏れも周波数は関係ないと思うが、OS は存分に関係ある気がする。
(i==j==i) /* i=j=1 なら真 */ (i!=j==i) /* i=j=0 なら真 */
ミスポ (i==j==i) /* i=j=1 なら真 */ (i==j==!i) /* i=j=0 なら真 */
あぁ〜 (i==j==!i) /* i=j=0 なら真 */ も、ダメぽ… 誰か考えてぽ
(i==j==i) /* i=j=1 なら真 */ も、ダメぽ… ダメダメぽ… 首吊ってくるぽ…
後者なら ( !( i | j )) /* i=j=0なら真 */ とかは?前者はいまいち出てこないな。
>>407 ちょっと変形すりゃできないか?
!((i-1)|(j-1))
409 :
デフォルトの名無しさん :03/07/12 22:22
固定小数点の実装の仕方を教えてください。 解説しているサイトがあったらそれでもいいです。 環境はWindows2kです。 処理系はmingwでもvcでもC系ならなんでもいいです。 ちなみに32bitの固定小数点とfloat型は、 一般的にどっちが速いんでしょうか?
410 :
デフォルトの名無しさん :03/07/12 22:26
精度はそんなに必要ないです。
>>409 今時のCPUなら下手するとfloatのほうが速かったりするが
もまいらHacker's Delight読め。
>>409 src と dst が int なら最後に変換がない分固定小数点の方が速い
src と dst が float なら最後に変換がない分浮動小数点の方が速い
それくらい速度差って余りないよね。
ただ、掛け算、割り算が shift や lea に置き換え出来たりするとまた話が違ったり。
つーか、スレ違いだ。
414 :
デフォルトの名無しさん :03/07/13 01:46
ありがとうございました。 そうですね、スレ違いっぽいと自分でも思ってました。 (固定少数点はトリッキーぽいかなと思ったけど) とりあえずfloatで満足する速度が出るか試してから また考えます。
typedef float static_real; #define STATIC_REAL_VAR(var) (var) C++なら演算子のオーバーライドとかできるから固定少数点にした方がいいとおもったのを それにしておいて、不満があったら作るのも手。
416 :
デフォルトの名無しさん :03/07/13 03:53
ひとりよがりということなら、C言語に於いて foo.h: typedef struct foo *FooP; void foo_afo(FooP p, 略); foo.c: struct foo { 略 }; void foo_afo(FooP p, 略) { } メンバ変数の情報隠蔽のみだが、一部の同僚には非常に不評であった。
戻り値の型のあとで改行する人は大嫌いです。
418 :
デフォルトの名無しさん :03/07/13 03:57
こんなのあった。 char *p = NULL; printf("p = %s\n", p ?: "<NULL>");
>>418 printf("p = %s\n", p ?p: "<NULL>"); の間違いか?
あぼーん
421 :
デフォルトの名無しさん :03/07/13 04:07
>>419 ぶー、C言語的には間違えていません。
結構知られてないのね。
オペランド省略できるんだ?
>>422 Perl / Java だと出来ないみたい…
C言語ってトリッキーだねえ
>>421 ANSI Cでは許さないとgccが言ってきたぞ。警告ではあるが。
gccがぶーたれるなら規格外なんだろうなあ。 調べるのが面倒臭くなった…。
-ansi -pedantic ここまでやらないと言ってこないけどね。
427 :
デフォルトの名無しさん :03/07/13 10:22
トリッキーかは知らんが int A;//Aは任意の数 A%4; は A&3; に等しい。 以外に知らない奴多いが「割る数」が2^n(n=整数)なら 2^n-1で&したのと同じになる。 50倍ほど速くなったから、知っとけ。
428 :
デフォルトの名無しさん :03/07/13 11:01
>>427 それって基本中のキホンだぞ。
ホンキで知らないヤシが多いなんて思ってるのか?
>>427 それくらい最近のコンパイラなら最適化でやってくれると思うけど。
前どっかのスレで書いたコード 多分どんな型でもOKなSwapマクロ #include <stdio.h> #define Swap(a,b) \ {\ char static_assert[sizeof(a)==sizeof(b)];\ typedef struct { char buf[sizeof(a)]; } temp;\ temp t=*(temp *)&a;\ a=b;\ *(temp *)&b=t;\ } int main(){ int a=0,b=1; Swap(a,b); printf("a=%d,b=%d\n",a,b); }
>>431 構造体を作るよりも配列にmemcpyした方がいいと思うけど
433 :
デフォルトの名無しさん :03/07/13 12:29
>>428 うち、某大手ゲーム会社だけど、メインプログラマでも
それ知らない奴いるんだよね・・・・
まあ、そいつはメインとは言っても、他のチームのコピペ改造だけで
作ってる奴だけど。
>>433 うーん、それはちょっといただけないNa-。
>431 C++ならテンプレートで済む話だね。 昔はsizeof()使うマクロとかよくやったけど。
俺も某ゲーム会社でプログラマしてます。 &は使わずいつも%を使ってます。 ですが変数の型はちゃんとunsignedにしてますから 最適化により同等のコードが生成されているはずです。 だから俺のコードで&使えるところで%使っている場合でも見下さないで下さい。 可読性とかを優先しているだけです。
そうか、% か…
>可読性とかを優先しているだけです。 スレ違い
>>437 どんなコードがよく最適化されるかを精査した上で書くと
見た目素直なコードばっかりになるね。
>>431 揚げ足取りだが
Swap(a, b);
最後のセミコロンはいらん
MFCでCArray使ってて、配列要素から要素番号を得る方法が ないと言われて作ってあげた関数だが↓ int CLine::GetIndex(CDoc *doc) { int iRet = int(this - doc->m_lines.GetData()); return iRet; } ・・・別にトリッキーじゃないよな。「thisからCArray.GetData()を 引けばいいだけじゃん」と何度教えても、VBメインの香具師には 伝わらないかと思った。
>>443 そういう式も「ポインタの概念の理解」の範疇なのかな・・
ひっかかる人は大変そうだ。
ところで、そこではintへキャスト(というか明示的型変換)する必要ないよね。
ただ引くだけで結果型はintだし。
(キャストは書き間違えるとつらいので)
ptrdiff_t
確かに
漏れも、何でキャストしたんだろうと思ってやってみたよ。VC7だと、 typedef _W64 int ptrdiff_t; なんでワーニングが出るんだ。
>>448 ああ、Win64版コンパイラを使うときは問題が起こるぞっていう予告警告か。
予告犯罪みたいだな
>>429 遅レスだが、
Borland C++ Compilerは、
%4のアセンブラコードを出すよ。
あと、マジで知らん奴はいるから。
偶数・奇数の判定も%2より&1のほうが速い?
最適化のされかた具合によりますが、 % は副産物として商も求められているかも…です。
符号付きかどうかでも変わる気がする
ん?そういや負の値の余りってどうなるんだ? -5 % 3 とか 9 % -7 とか ?
正負混合のときは符号は処理系依存だったと思う。 C99では決まってるんだっけか。
そんなときのためにdiv関数があるらしい。(Cスレより)
>>451 最適化レベルをあげても?
もしそうならそのコンパイラをつくった人たちも「それ」を知らなかったりして。
は?
>>451 unsignedならちゃんと最適化したと思ったが。
>>431 {}で囲むよりdo {} while(0)が良いかも。
if(flag) MACRO; else MACRO2; MACROの後ろの ; 対策ですね。
>>431 char static_assert[...];
より
typedef char static_assert[...];
の方が良い。
皆さんの意見を総合。C++大すきっコなので使うことは無いですが。 #include <memory.h> #define Swap(a,b) \ do{\ typedef char static_assert[sizeof(a)==sizeof(b)];\ char temp[sizeof(a)];\ memcpy(temp,&a,sizeof(a));\ memcpy(&a,&b,sizeof(a));\ memcpy(&b,temp,sizeof(a));\ }while(0)
memcpyはstring.h
>>462 型定義なら実際に領域が取られることはない。ということか。考えたなぁ。
オリジナルと比べると、aとbの型が違っててもサイズが同じなら動くように 改良されてる?
>>431 そのstatic_assertの使い方は_AC_COMPUTE_INTのに似てるな。
あっちは[1-2*(sizeof(a)!=sizeof(b))]で負になるようにしてるけど。
switch(0) { case 0:; case sizeof(a)==sizeof(b):; } メリットなし。
>>469 static_assertはmodern c++ designに書いてあったのをパクッた。
__∧_∧_ |( ^^ )| <寝るぽ(^^) |\⌒⌒⌒\ \ |⌒⌒⌒~| 山崎渉 ~ ̄ ̄ ̄ ̄
template <bool>struct static_assert; template <>static_assert<true>{}; #define STATIC_ASSERT(expr) typedef static_assert<( expr )> static_assert_tmp##__LINE__; BOOSTのヘッダー見たところ、こんな感じだった気がする
#define STATIC_ASSERT(expr) typedef struct {\ char dummy[(expr)?1:-1];\ } static_asserttmp##__LINE__; #define STATIC_ASSERT2(expr) typedef struct static_asserttmp_2_##LINE__ {\ char dummy[(expr)?1:-1];\ } static_asserttmp##__LINE__; 単体で使えるC版を考えるとこうかな 追記:1行で2つ使うと悲惨なことになるかも。 プリプロセッサ内部で使う場合は要注意
int c = 1/(sizeof(a)==sizeof(b)); 零除(ry
>>476 それってエラーになるって決まってるんだっけ?
保守
簡単な言語系作ってる時に、式の評価でこんなコード書いてみたんだけどどでしょ? while(((op=C_ADD,opl=6,len=1,*p=='+') || (op=C_SUB,opl=6,len=1,*p=='-') || (op=C_MUL,opl=7,len=1,*p=='*') || (op=C_DIV,opl=7,len=1,*p=='/') || (op=C_MOD,opl=7,len=1,*p=='%') || (op=C_FUNC,opl=8,len=1,*p=='(') || (op=C_LAND,opl=1,len=2,*p=='&' && p[1]=='&') || (op=C_AND,opl=5,len=1,*p=='&') || (op=C_LOR,opl=0,len=2,*p=='|' && p[1]=='|') || (op=C_OR,opl=4,len=1,*p=='|') || (op=C_XOR,opl=3,len=1,*p=='^') || (op=C_EQ,opl=2,len=2,*p=='=' && p[1]=='=') || (op=C_NE,opl=2,len=2,*p=='!' && p[1]=='=') || (op=C_GE,opl=2,len=2,*p=='>' && p[1]=='=') || (op=C_GT,opl=2,len=1,*p=='>') || (op=C_LE,opl=2,len=2,*p=='<' && p[1]=='=') || (op=C_LT,opl=2,len=1,*p=='<')) && opl>limit){ // 演算子がある間継続 }
>>479 どうせならこう書くな。
while((*p=='+') ? (op=C_ADD,opl=6,len=1) :
(*p=='-') ? (op=C_SUB,opl=6,len=1) :
…
トリッキーではないな。ちょい読みにくいし、実行速度の面で無駄が多い。 じゃあどういうコードが良いんだろう、と言われると迷うな。考えてみよう
whileでトリッキー??にする理由が分からない。 とりあえず毎回op, opl. lenに代入する必要はないから 480に一票。 デバッグ楽にするために俺なら*pのswich文かな。 全くトリッキーではなくなるが、タイプミスが減る。w
>>481 > 実行速度の面で無駄が多い。
479も480も最適化される可能性が他界
(op=C_ADD,opl=6,len=1,*p=='+')
は、*p=='+'の結果によらず、
op=C_ADD,opl=6,len=1が実行されるよね?
だったら、
>>479 と
>>480 が同じような最適化されるとは思えないなぁ
って、試せよ>>ワシ
でもその後で上書きされるなら、省略される可能性もある。
逆に、
>>480 のコードが再配置されて
>>479 みたいになることもある。
>> 逆に、
>>480 のコードが再配置されて
>>479 みたいになることもある。
書いてない処理、コンパイラが足す訳ないじゃん。あほか。
はぁ?
>>486 は放っておくとして、
*p=='+'が
真なら上書き
偽ならそのまま
代入が1回は行われるから、同じにはならんが近いのは
出してくれるかもしれん
でも、最適化を期待して、読みにくいコードを書くのはどうかと。
普通、最適化を期待して、読みやすいコードを書くものではないかと。
>>488 > でも、最適化を期待して、読みにくいコードを書くのはどうかと。
ではなくて、「結果的に
>>479 的になることもある」といってるだけ。
明らかに479より480の方がステップが少ないので、 479が最適化されて480になることはあっても 逆はないだろと言いたかった。 479は変数代入後に*pを評価しろとコンパイラに 指示している。480は*pを評価してから代入だろ。 「書いてない処理」とは評価前の代入のことだ。 488も同じ話をしていると思うが.
そもそも479は、「,」演算子で区切られた式は左から順に評価されることが保証されている、というC++の仕様を知っているのか?
アホは言い過ぎた。夜中だし酔ってたんでな、謝るよ。 漏れは479でも480でもないが、480の方が速いだろうと思う。 その点は譲りたくないな。w スマンカッタ
藻前、案外いい香具師だな
(^^)
480が479より速いことはあっても、479が480より速くなることはないのはいいよね?
コンパイラ次第だってば。まぁ479が480と同じになるくらいならともかく、 より速くなることはたしかに考えにくいがな。
最小のwindowsプログラム(ただし窓を表示)って何byteになるだろ? 356テトリススレで話題になってたので気になった。
窓表示させるだけなら…
何気にあのスレ木になっちゃうんだよね。7行とか制約があるの大好き(藁
COMファイルで実装なんて出来ないよな? exeファイルならシンボル解決だけで辛そう。 ExitProcess、という文字列だけで10byteだし
エディタで↓と書いて拡張子vbsで保存。 WScript.Echo
俺このスレ好きだなぁ。いつ来ても新しい話題が盛り上がってるし
>>503 それは却下でそ(笑)。多分MessageBoxも却下だと思われ。
ウィンドウプロシージャを呼び出すのを前提にするといいかもね。
ところで、このスレでこのOS依存の話題を続けてもいいのかなぁ?
いぜん漏れがフロー読み違えたコード。正常時および異常時のループの回数を考えてくれ: fRet = FALSE; while(1) { // 中略 if (GetAttribute(pNode, FROMY, strFromY) == FALSE){ TRACE("Not found %s Attr\r\n", FROMY); strFromY = "0"; break; } if (GetAttribute(pNode, TOY, strToY) == FALSE){ TRACE("Not found %s Attr\r\n", TOY); strToY = "0"; break; } fRet = TRUE; break; } 何がトリッキーかというと、この香具師の組織では「複数return禁止」「goto禁止」だったんだ。 だからってこれならいいのかと小一時間・・・ 「頼むからgoto使ってくれ」と言いたくなったよ。
>>505 複数リターンは下手するとメモリリークの原因にもなりかねんから
なるべく使わないようにしてるけど。
while(1) { break; } や do { } while (0);
もいいか悪いかは別としてgotoの代わりとしては
よく使われてるんじゃないの?
>>505 すまん、あおりではなく素でどこが問題なのかわからないんだけど
while(1)よりはdo whilte(0)のほうが繰り返さないということが読み取り易いかな。 しかしgotoなんか使う場面とは思えんなあ。 一般的にgoto禁止でも普通ぜんぜん困らんが、複数returnはむしろリファクタリングで 積極的に使うべきものだから禁止ってのは辛いな。
>>506 今時はスマートポインタなどで確実にデストラクタでガードするようにするので
複数returnは基本
>>509 trueやfalseではなく1とFALSEを使っているところから、C++ではなくCだろうと思われ。
ああ、やっとわかった。 これはそんなにトリッキーでは無いんじゃないかな? 一般的なスタイルなら、do...while(0) だから、そちらの方が読みやすいけど。
元コードは、CライクなC++です。COMというかMSXML関係。 漏れはループでないシーケンシャルな処理には「決して」while/do/forは使わん 主義なのだが(言ってることおかしいか?)、どうやら世間ではそうでもないのかな? 特に、whileブロックの最終行にbreak;は生涯で一度も書いたことが無い。 少しは自分の社会勉強になったかな。w
いや、「決して」というのを除けば多数派だと思う。
このアプリの他の部分は、いかにも教科書通りなMFC-WIN32アプリなんだが、GDI関係とかも 最新のスタイルならきれいにスマートポインタで開放・復旧できるもんなのかな? 漏れの知識は少し古いので分からん。ので、古典的だがgotoでexitラベルに飛ばして、そこで finally()処理をしてからreturnというルールにした(かった)。
もちろん do { } while (0); と書かれていれば、この場合は何も理解困難なことはなかった。
要は自分の考え方と違うソースが読めないんだろ?
漏れは同じ手に引っかかった事があるから、
>>505 の気持ちはわかる。
goto使えとは思わんかったけど、do{}while(0); 使えよとは思った。
…更にその後 do{}while(0); は使うなと言われて唖然。
>>516 漏れに文句いわれた香具師は、「goto、複数returnありの組織とは思わんかった」つっとった。
その時もだが、ここに書いてみて改めて勉強になったよ。w
漏れのgoto擁護、落語だと思って聞いてくれ: 1) 「プログラミング言語C第二版」(K&R)には、 「(gotoの)最も一般的な使用は、深く入れ子になった構造での処理を中断させる場合である」 とある。 2) 「プログラミング言語C++第三版」(Stroustrup)には、 「gotoを使ってもよいまれなケースのひとつは、入れ子状のループ、switch文からの脱出である」 とある。 3) C/C++の子孫であるJavaおよびC#には、finally{}節が存在する。 ・・・以上のことから漏れ個人は、C/C++においては、たとえループやswitch文がネストしていない 場合でも、goto finally;型の用法は良性と見ていたりする。 Java/C#との論理的互換性・移植性を考えても、その使い方は悪性ではない。というか、見かけ 上のgotoや複数returnを回避するためにループ構文を使うのはよくないんではないか、とか思う。 (gotoスレにいくべきだったかも知れんな)
>>514 GDIだろうがなんだろうが出来るし、例外処理対策を考える場合
デストラクタでやる以外にない。
505自身を貶すつもりはないが、今のプログラマは505程度のコードでつまってしまうレベルということはわかった。
(⌒V⌒) │ ^ ^ │<これからも僕を応援して下さいね(^^)。 ⊂| |つ (_)(_) 山崎パン
>>521 ケースバイケース。
漏れは↓のようなコードのデバッグで詰まったことがある。
・関数仕様:
「ある条件」を満たすまで待つスレッド。
・症状:
「ある条件」を満たすのを待たない
・実装:
DWORD hoge_thread()
{
:
while(1){
int flg = hoge(); // 実際はこの中でループ。判定式が間違っていた。
if( flg == ERROR_HOGE ){
break;
}
break; // ←バグだと思って消した
}
:
}
break のせいでループしないと思い込み、
消したら今度はフリーズしたもんで
小一時間考え込んでしまったよ…
>>523 まあ始めてみたらそう思うだろうけど、
小一時間考え込むのはデバッグのセンス悪杉
がんばれ
>>524 漏れのセンスが悪いと決め付けるんじゃなくて、
hogeの中身が小一時間悩むに相応しい内容だったとか、
"小一時間"に誇張が含まれてるとか、もっと想像力働かせて欲しい…
…などと書くと「コイツはダメな仕様書書く奴」とか言われそうだな。
>>525 そういうのは織り込み済みで、センスが悪いんだろう(藁
DWORD hoge_thread() { : while(1){ int flg = hoge(); // 実際はこの中でループ。判定式が間違っていた。 if( flg == ERROR_HOGE ){ break; } break; // ←バグだと思って消した } : } そもそもこんな関数作るやつのセンスが無いんだけどな
whileブロックの最後でbreak;やっぱあるんだな。w 引っかかる香具師も俺だけじゃないらしい。 トレースに費やした時間よりは、書いた香具師に 問いただした時間のほうが長かったよ。そいつが 別の仕事入ってたんで、同じ形式のコードを5箇所 位自分で改善しないといけないのが一番の苦痛だった。
前スレで、 switch(...) { case LABEL_A: { ... } if(false) case LABEL_B: { ... } if(false) case LABEL_C: { ... } ...(共通処理) } というコードがあったけど、このコードはまず所見では理解されないだろうなぁ。 書きたくなる気持ちは非常によくわかってしまうが、インライン関数化すべきか。
>>530 そういうときは共通処理を関数化するか、
switchをもう一段入れてる。gotoでまとめることもあるけど。
switch(X) {
case LABEL_A:
case LABEL_B:
case LABEL_C:
switch(X) { // Xは上と同じ式
case LABEL_A:
...
break;
case LABEL_B:
...
break;
case LABEL_C:
...
break;
}
...(共通処理)
break;
....
}
>>531 (あくまでも個人的にだが)美しくない気がする。自分では書きたくない。
530の方がトリッキーな分まだ美しいが可読性は著しく落ちるな。
しかし難しいよな。たとえば共通処理が2〜3行程度だった場合
わざわざインライン関数を書くのもなんだか美しくないし、
かといってcaseの中身を別々の関数にしようと考えてしまうと
2〜3行のcaseが10個くらいあった場合に悶え死にしそう。
どこかの組織で書く場合ならば、やっぱり531を選択せざるをえないけれど、
その場合でも可能であれば下のようにして書きたいな。
switch(...) {
case LABEL_A: ...; break;
case LABEL_B: ...; break;
case LABEL_C: ...; break;
...
}
switch(...) {
case LABEL_A:
case LABEL_B:
case LABEL_C:
...(共通処理)
break;
}
自分がメンテナンスするコードなら喜び勇んで530と書くけどな
漏れなら素直にこう書く。 switch( X ) { case A: ...; break; case B: ...; X = A; break; case C: ...; X = A; break; } if( X==A ){ (共通処理) }
その後でXを使ったり、Xがconstだったりしたらどうする? あまり素直ではないと思うぞ。それに532の方が読みやすい。
Xがconstなら、そもそもswitchになんぞ入れない。
Xを再利用するならXのコピーを作る。
各処理を関数化するか否か迷う程度の大きさなら、
変数増やしてもさほど可読性は落ちないだろうし。
共通処理が1つでなく、組み合わせが多ければ
>>534 と書くけど、
switchは別々の関数に分ける。
533が美しくないと思う論拠 ・533はソースを読む人の意識からすれば、たとえばswitch文をあまり詳しく読まずに 下のif文まで読んでしまった場合に、そのif文が実行されるのがX==Aの場合だけだと 誤解される可能性が高い。532であれば、矛盾せずに読める。 ・その後Xを用いた処理がある場合は変数をひとつ増やす必然性があるが、 ただ条件分岐のためだけにflag変数をひとつ増やしてしまうと、 同じ関数内で同じ意味の変数が出来ることになり、後のメンテナンスで問題を誘発しやすい (間違えてXを使ってしまった、というバグが出ることは十分にありうる) という意味で、533は美しくないと言える。 グループでのプログラミングの場合は可読性の低いプログラムを書くべきではないし、 自分さえわかればいいというのであれば530だな(笑)
分かりやすさのために冗長さを我慢するなら、533のような中途半端でなく、 普通に531-532かな。言い方を変えれば533も「トリッキー」だろう。 前スレ読んでなかったんで、530は初めて見た。いろいろあるもんだな。
昨日、 if (a == b == 0) // something; って書いちまってたよ。当然、 if ( (a == b) == FALSE) // something; と解釈されるよな。もうだめぽ現役引退か・・・
bool型の暗黙型変換が許されない言語に乗り換えて生きろ
>>535 constをswitchに入れることなど普通です
ex:
int function(const int mode) { switch(mode)...
>>540 int型引数を const にする意味があるのかと小一時間。
参照なら分かりますが。
フラグを使う点や、ここがトリッキースレであることに目を瞑れば
↓が一番素直で簡潔だと思いますが。
フラグで可読性が落ちるほど大規模なら、素直に関数化すべきだし。
関数コールに比べりゃ、bool値の演算の方がコスト安いし。
bool flg = true;
switch( X ) {
case A: ...; break;
case B: ...; ; break;
case C: ...; ; break;
default:
flg = false;
}
if( flg ){
(共通処理)
}
(処理)
if( flg ){ // 再度分岐が必要な場合に有利
(共通処理)
}
リファクタリングの本では、複数return回避のみが目的の fBreak 的フラグも 批判しているよね。
goto使えば一気に簡単になるぞ。 switch(...) { case LABEL_A: ...; break; case LABEL_B: ...; break; case LABEL_C: ...; break; default: goto no_exec_common; } ...; /* 共通処理 */ no_exec_common:
漏れもgoto割と擁護派だが、無条件に野蛮人扱いされるのが辛いな。
>>545 >無条件に野蛮人扱い
こういう香具師が野蛮人だと思いますw
無駄にフラグ使って読みにくくするなら gotoや中途returnの方がよっぽどましってマジで思う。
ここって、トリッキーなコードのスレですよね? マ逆なスレに見える漏れは逝ってヨシですかね?
>>544 参考になった。
gotoを使う発想は、日頃から使っていないと出ないのかも。
>>548 マ逆?
真逆
まさか
switchの中の共通処理をgotoでまとめるときは、 共通処理自体もswitchの中に書くなあ。 外に書くとなんか気持ち悪い。
コードでなくアルゴリズムだが、むかしトリッキーに思ったものを: 普通、ビジネスアプリのデータフォーマットが変わるメジャーバージョンアップの場合は、旧データ変換専用のコードを書くと思う(漏れはな)。 特に複数の過去バージョンに対し読み書き双方向をサポートする場合は、ターゲット毎にコンバータを書いたりするのが一般的ではないかな。 漏れが見た某「割と有名」アプリはレイヤ方式というか、 V5フォーマット(最新) ↑ ↓ V4フォーマット ↑ ↓ V3フォーマット ↑ ↓ V2フォーマット ↑ ↓ V1フォーマット と連続的に世代変換する方法で、例えば「V2形式を読んでV4形式で保存する」というような事を可能にしていた。 まだメモリやディスクの制約が厳しい時代に書かれたコードで、場所を食わない上に最新バージョンに対しては高速に動作する。 知られたテクニックなのかも知れんが、個人的には面白いな〜と思った。
>>553 上から下への矢印はなんかおかしい気がする。
フォーマットを変えるからには、下のフォーマットでは実現できない
何らかの付加情報があるはずだが。
>>553 ,554
もちろん切り捨てるしかない。例えばAdobe Illustratorは業界標準だが新版の普及に
何年もかかるため、納品先の都合で2バージョン前のファイルを書く必要性も生まれる。
553の方式では、たとえばフォーマットが先祖がえりをする場合などに 本来切り捨てる必要の無い情報を切り捨てたりしてしまうのが問題か? しかしそんな事態はまず起こらないだろうけれど。 それと、データサイズが膨大だった場合は処理が冗長になりよろしくないね。
学術的なトリッキー希望 トリッキーなコンパイラを作るとか
なんでsage進行なんだろう。夏の厨房防止だとすると効果覿面だな
2chのルールよく知らないんだが、いい加減落ちそうだよなw かと言って自分が上げるのもなあ・・・
sageたままでも落ちないよ。 最終書き込み日時が考慮される。
レス数も少ないやつから落ちてくし
#define die (exit(1),0)
#define BEGIN { #define END } トリッキーというよか、こんなの書いたら終わりだな(藁
落ちません落ちません。 とりあえずsage進行で行こう。 昔、VC++でTODOにタグジャンプを付けたいときに、 ものすごくトリッキーなコードを書いた記憶があるな。 コンパイルエラーとかが出ると、VCでは、 C:\project\foo\foo.c(123) error C4001: 何らかのエラー。 C:\project\foo\foo.c(123) warning C4002 : 何らかのワーニング。 という形になるのですが、それと同様に C:\project\foo\foo.c(123) message : TODOなどのメッセージ という出力をするマクロを書いた。 これをやると、便利なことにF4でタグジャンプできるので、 TODOメッセージや連絡事項などを忘れることなくソース中に書ける。 完全な処理系依存だとおもうけど、発掘したら公開します。
眠れないのでカキコ
>>568 もちろんそれを使うのだが、このプラグマはメッセージを純粋に表示するだけで、
ファイル名や行番号は出してくれないのだ。
で、自分で出力しようと思って、
#define TODO(x) message( __FILE__ "(" __LINE__ ") message: " x )
という定義を書いてみるわけだが(#pragma TODO(...) という使い方を想定)、
__LINE__ が文字列ではなくて数値だということでコンパイルエラーが出る。
そこで、文字列化マクロを使用して
#define _TOSTRING(x) (#x)
#define TODO(x) message( __FILE__ "(" _TOSTRING(__LINE__) ") message: " x )
のように書いてみることを大抵思いつくと思うけど、この出力結果は
C:\project\foo\foo.c(__LINE__) message : メッセージ
となってしまう。__LINE__ が展開されないまま文字列化されてしまうんですよ。
というわけで、正解はこちら。 #define _TOSTRING(x) (#x) #define _THRU(x) _TOSTRING(x) #define TODO(x) message( __FILE__ "(" _THRU(__LINE__) ") message: " x ) 間に一つ何もしないマクロをはさむことにより数値展開された上で文字列化されます。 コンパイラのプリプロセッサ内部で構文解析木を作るときに、一度記号表へ入れられるか 直接処理されるか、その内部構造の隙間を利用したトリックですね。 種明かししてしまうと簡単なんだけど、このコードはそこそこ気に入っています。 (ただ手元にソースが無いので、思い出しながら書いているので間違っていたらごめんなさい)
念のため突っ込ませてくれ。Cの仕様で #error ほげほげ とか書けるのは知ってるよな? エラーになるので、ワーニングには使えないが。
>>571 コンパイルエラー出したくないから TODO なんだと思うが・・・
>>571 エラーになったらビルドが止まりますから、それはいやですよね。
面白いことに、出力の"message"のところを"error"や"warning"に変えると
なぜかエラーやワーニングのカウントに入れられてしまう罠@VC
良いこと聞いたからage! たいけど我慢してsage!
>>570 実際に VC でやってみた。
_TOSTRINGマクロは ()でくくるとコンパイルエラーになりまつ。
#define _TOSTRING(x) #x
それから、埋め込むときは
#pragma TODO("さっさと実装しろ。")
のように書く必要あり。
#pragma もマクロに埋め込めるとさらにウマーだが。。。
>>575 サンキュー。やっぱうろ覚えじゃダメだな。
今自分の環境(.NET)でやってみたら、タスク一覧に出てこないから
F4ジャンプなどが出来なくなっている。出力からのタグジャンプは使えるから
使いにくくなったわけじゃないけど、.NETになってしまったら
出力をチェックする人は少ないかもしれないね。
で、相変わらず、自分で#pragma messageを使って出した偽のエラーメッセージに
統合環境は律儀に反応してくれます。
IDEとコンパイラは、標準入出力のみで繋がっているんだね(笑)
>#pragma もマクロに埋め込めるとさらにウマーだが。。。
それ、できるのかなぁ?出来たらかなりトリッキーぽ
ちょっと追記。.NETな人は、 #define TODO(x) message( __FILE__ "(" _THRU(__LINE__) ") : warning : " x ) を使えばタスク一覧にTODOメッセージが出ます(ついでにコンパイラが警告を勘違いして加算します)。 これで.NET環境でも便利に使えるかもしれない # けど.NETなら標準でこういうツールを用意してそうな気もする。調べてないけど
>#pragma もマクロに埋め込めるとさらにウマーだが。。。 _Pragma… 残念ながらVCじゃ使えないね。
有用なトリックだな。利用させてもらおう。これはいい。
VC++6.0英語版で調べてみたが、↓でも反応するね。 #define TODO(x) message( __FILE__ "(" _THRU(__LINE__) ") : ToDo : " x )
なぁ、このスレageたいんだけどダメ?
C++スレから面白いものをみつけてきました。 void *operator new ( size_t Size , int lib); void __cdecl operator delete(void* p, size_t Size); #define new new(1) #include "a_lib.h" #undef new #define new new(2) #incluede "b_lib.h" ヘッダファイルによってメモリ管理方法を変更したい場合のコードです。 しかしこの場合、deleteがうまく出来ないので、なんとか解決する方法を模索しましょー
582結論でたぽ
保守。ネタをふれなくてすまん
漏れのブラウザでは674/727になってる。どこまで下がれるか試すスレか?
板の整理が行われたら一気に上がるだろうけど。 なんにせよ厨房のいないスレってことか。すばらしい 誰かテンプレートを使ったトリッキーなコード知らない?
もう少し耐えたいけど、流石に710まで着たらageちゃってもいいか
ageる必要性がわからないのだが。 sageでもちゃんと定期的に書き込んでいれば、消されないはずじゃなかったっけ? 正直、厨房が紛れ込まない今のスタイルがかなり気に入っているので
ここより下のスレをageないように気をつけていたら まぁ大丈夫だろう。 ただ、レスがあっても最下層にいていると落ちそうなので怖いなと。 糞スレに紛れて厨房がこない雰囲気は俺も好きだが。
簡単な話で、落ちたら次スレを立てればよろしい。 それよりトリッキーなコードキボンヌ
倉庫行き判定は最終書き込み時刻と明言されているのに
うっかり上げたら袋叩きの悪寒・・・
1:アンチデバッグコード 2:テンプレートによる可変個引数 どちらを書くか考えながら寝る
594 :
デフォルトの名無しさん :03/09/11 18:21
ウヒヒ
>>593 どっちも面白そうだな。
誰かトリッキーなコードを書いてくれることを楽しみにしてるぜ(゚∀゚)b
いや、俺はそんな実力無い…スマソ_| ̄|○
じゃ、アンチデバッグコードを書こう。 どうでもいいがVS.NETは結構重い気がする。 昔どこかのスレで見たんだけれど、調べてみたけれどどこかわからなかった。 間違いなく倉庫に行っているとは思うんだけれど、作者の人パクってすまん。 VC++のみでしか使えないのが残念だが、Windowsでのアンチデバッグコード。 デバッグ状態で実行すると異常終了するように出来ている。 bool flag=true; __try { __try { DebugBreak(); } __except(GetExceptionCode() == STATUS_BREAKPOINT) { flag = false; } } __finally { if(flag) exit(EXIT_FAILURE); } // normally execution これでも十分きついが、さらにわかりにくくするためには 一見何気ないコードの中に動的ランダムにint 3hを入れることにより ブレークポイント例外を飛ばせばいいんじゃないだろうか。 自分がクラックするときのことを考えると本気で萎えそう。 ちょっと有用なトリッキーコードでした。 今度はかなりトリビアなトリッキーコード行きます。
「絶対にデバッグしないでください、法に触れます」 と書いておいて、デバッグ状態で走らされたら 全HDフォーマット&ネットワークファイル全削除するとか。 自分がクラックするときのことを考えると本気で泣きそう。
>>597 トリッキーというか…トリッキーなのかなあ(苦笑
まあもっとも法のほうは多分そんなデバッグしてはいけないというのを
守ってくれるようなのは、少なくとも現行日本には無い希ガス。
実際にそんなことしたら負ける雰囲気。
どうせならもっとはっきりと、
「絶対にデバッグしないでください。
もしした場合ハードディスクのデータ及びネットワークファイルを消去します。
同意いただけない場合は使用してはいけません」
と利用規約に書く。
まあ、それでも裁判したらどうなるか怪しいけどナ
トリッキーかどうかはわからないけど、 int ( int, int ) のような関数型を受け取って、引数タイプリストを返すもの。 タイプリストは、Loki のやつ。 template< typename R > struct RaramList { typedef Loki::NullType Result; }; template< typename R, typename P1 > struct ParamList< R ( P1 ) > { typedef TYPELIST_1( P1 ) Result; }; template< typename R, typename P1, typename P2 > struct ParamList< R ( P1, P2 ) > { typedef TYPELIST_2( P1, P2 ) Result; }; .... と、必要な分だけ特殊化させておく。そうすると、 ParamList< string >::Result; // NullType ParamList< void ( int, int ) >::Result; // TYPELIST_2( int, int ) ParamList< int ( char*, int, int ) >::Result; // TYPELIST_3( char*, int, int ) で、引数リストが完成。 これを利用して、Loki の Functor を書き換えると、 Loki::Functor< int, TYPELIST_1( char*, int ) > と、 Loki::Functor< int ( char*, int ) > で同じ動きをさせることも出来る。
間違えた。ついでに 600get?
>>599 ×> Loki::Functor< int, TYPELIST_1( char*, int ) > と、
○> Loki::Functor< int, TYPELIST_2( char*, int ) > と、
>>598 もちろんネタだけどね。
>>599 Lokiについて知らないので良くわからないが面白そう。
差し支えなければ少し解説してもらえると
>>601 int foo( char*, int ); という関数があったとき、
&foo の型は 「 int (*)( char*, int ) 」、*foo の型は、「 int ( char*, int ) 」
(違っていたら、指摘よろ)
boost::function だと、この関数型(?)で関数オブジェクトを実体化できるが、
Loki のファンクタは、以下のような定義になっていて、対応していない。
template
<
typename R,
class TList = NullType,
class ThreadingModel = DEFAULT_THREADING
>
class Functor;
第一テンプレートパラメータに戻り値の型、第二テンプレートパラメータに、
引数の型を入れたタイプリストを指定するようになっている。
(つづく)
Modern C++ Designを買ってきます。続きよろしく(笑
…続けようと思ったけど、すれ違いになるからやめ。 関数の型でファンクタを実体化できるようになると、 以下のようなことが出来てちょっとうれしい。 typedef int ( func_type )( char* , int ); boost::function< func_type > fn( foo );
最後に。 結局、関数型と、タイプリストの間を自在に行き来できるコード template< class R > struct Conv; template< class FR > struct Conv< FR () > { typedef TYPELIST_1( FR ) Result; }; template< class TR > struct Conv< TYPELIST_1( TR ) > { typedef TR ( Result )(); }; あとは、ParamList と同じで特殊化をどんどんしていくだけ。 で、何に使うかは不明(w
結局ってなんだ... _| ̄|○ 意味もなく調子に乗りすぎたので、回線きって首(ry)
関数ポインタといえば今回のCマガの 112ページからの記事はどう思う? 引数については、Argumentという型の引数を 1つ受け取る形式のテンプレートクラスのようだけど
>>609 読んでいて途中で眠くなったので要約希望
第29回 コールバッククラスの実装 今回は、関数の呼び出しに使うコールバクについて、 ベースクラスの実装からコールバックの集合体へと 解説していきます。 [はじめに] ノートPCを2度目の修理に出した。 液晶パネルが割れたのだが、見積もりが十数万円と いわれた。液晶パネルだけでなくHDやバッテリー などにも異変があるそうだ。 懐に余裕がないので液晶パネルだけ直してもらった。 修理後にHDの検査をしたら欠陥クラスタがたくさん 見つかった。おどろいた。 デスクトップPCなら自分で部品交換するのだが、 ノートPCでそうするのは怖い。開けたフタが 閉じなくなったりネジが余ったりしたらと思うと…
[メンバ関数へのポインタ] C/C++では関数ポインタはかなりの頻度で使われる。 例えば、(マルチスレッドで)スレッド生成関数へ スレッド関数を引数として渡されたり、qsortへ 比較関数を引数として渡したりしている。 関数へのポインタをほかの関数に与えておき、 必要に応じてそのポインタを介して関数が呼び出される ことを「コールバック(call back)」と呼ぶ。 「メンバ関数へのポインタ」と「関数へのポインタ」は 違うものである。(staticでない)通常のメンバ関数は インスタンスに対して適用される。例えば以下のとおり。 Foo f; f.print(); Foo::print(); // エラー!インスタンスがない メンバ関数には、インスタンスが暗黙の引数として 与えられることに注意すること。 メンバ関数は、通常の関数とは異なる宣言をする。 「クラス名::」で修飾されなければならない。 また、使用時には(暗黙の引数となる)インスタンスを 介して呼び出さなければならない。 関数へのポインタも、ポインタである。 コンテナへ格納した後に、格納順に呼び出したり 位置を指定して呼び出したりすることができる。 「メンバ関数へのポインタ」と「関数へのポインタ」は 違うと説明したが、混在してコンテナへ格納する方法を 以降で示す。
[コールバッククラス] 前提(or仮定or条件)として、呼び出す関数を Result function(const Argument&); とする。 コールバッククラスの仕組みは、3つのクラスで 構成される。 Callback ← FunctionCallback ← MethodCallback 以下に、クラスの抜粋を示す。 template<typename Argument, typename Resurt =void> class Callback { public: virtual Result operator()(const Argument& a) = 0; };
class FunctionCallback : Callback { public: typedef Result (*func_type)(const Argument&); Result operator()(const Argument& a) { return (*func_)(a); } private: func_type func_; }; class MethodCallback : Callback { public: typedef Result (T::*method_type)(const Argument&); Result operator()(const Argument& a) { return (t->*method_)(a); } private: method_type method_; T *t; }; FunctionCallbackは関数へのポインタを保持するが、 MethodCallbackはそれに加えてインスタンスへの ポインタも保持していることに注意すること。
[コールバックの集合体] コールバックを複数個まとめ、一気に呼び出す CallbackChainを以下に(一部)示す。 class CallbackChain { public: void execute(const Argument& a); private: typedef vector<Callback*> chain_type; chain_type chain_; }; CallbackChainにはCallbackを追加/削除でき、 登録されたコールバックをexecute()で一気に 呼び出せる。ただ残念ながら、このように 複数のコールバックを行ったとき、戻り値を 無視している。どうするかさんざん迷った。 いい方法があればぜひご一報を。 vectorでポインタを管理しているので、 ポインタ先のCallbackオブジェクトを ~CallbackChain()で正しくdeleteする 必要があることに注意すること。 この際、vector::erase()の扱いにも あわせて注意すること。 CallbackChainには基底クラスがないが、 これをCallbackから導出することも 考えられる。そうすればCallbackを ツリー状につなぐことが可能であろう。
[お試し] これらのクラスをどう使うのか、使用例と して整数の10/16/8進数表記を示す。 コールされる関数は void print_dec(const int& n) { cout << dec << n << endl; } の形式である。メンバ関数も似た形式である。 これらの関数はdec以外にhex/oct版がある。 本連載の第1回は「イベント駆動」という タイトルでObserverパターンを紹介した。 紹介したクラスには更に手を加えたバージョンが あるのだが、第1回ではそこまで紹介せずに終えた。 今回のCallbackはその解の1つである。 長い間待たせて正直スマンカッタ。
ではあらためて… 引数については、Argumentという型の引数を 1つ受け取る形式のテンプレートクラスのようだけど そこのところはどうなの? ところで、この記事の中で、CallbackChainのexecute()の 戻り値をどうするか迷ったということは明記しているが (いい方法があったら教えてとも書いてある) 引数(の個数)をどう考えたのかについては何も書いてないのよ。 どう考えたのだろう。 「Modern C++ Design」では、ここでさっそく(?) タイプリストがでてきたのだが。
コピペうざいよ
>>609 > 引数については、Argumentという型の引数を
> 1つ受け取る形式のテンプレートクラスのようだけど
> そこのところはどうなの?
漠然としすぎていて質問の意図がよくわからない。
どう問題だと思ってるの?
それより前にあったテンプレートの可変個引数の実装を教えてくれ
別に問題だとは思ってないけど、例えばあるところでは int func1(int); を使いたくて、また(同じプログラムの)別の場所では double func2(double, double); を使いたい時は、どのような解法を示すのか興味があった 他にもCallbackChainで、関数の型が単一でなく、 func1とfunc2を混在して追加/削除したいときとか
Callback って汎用関数オブジェクトのことでしょ? boost:::function + boost::bind + boost::signals を使えば解決じゃない? そういう話じゃないのか……?
俺、boostは使ったことないのよ。予想だけど boost:::function → いわゆるファンクタ boost::bind → いわゆるバインダ boost::signals → これが何か予想つかない 最後がわからない…ので、どう解決されるかわからない あと、この記事にのっているCallback って、俺には 説明が簡素に感じたんだ。たぶんこの記事を書いた人は 自分の中では解決できているのだろうけど、記事を 読んだ俺には「汎用」関数オブジェクトって気が しなかったのよ。「引数が1つ」専用関数オブジェクトと 感じたんだ。少なくとも、このままではfunc1とfunc2を 混在してChainすることができるとは俺には思えない。 それで、個数が変わった場合にこの記事を書いた人は どうしているのか興味があった。
Modern C++ Design読んで感激しまくり。 なんてトリッキーなんだ。しかも美しい。
あれはなんていうかトリッキーの塊だからな。凄いぞ。 …でも漏れ理解度25%未満だよ_no 修行してきます
いろいろリンク教えてくれてありがとう リンク巡って勉強するよ そしてboostも勉強するよ 長々とスレを汚してすまんかった
あ、このスレagaってたんだ。大人のスレだな。
631 :
デフォルトの名無しさん :03/09/25 17:38
boostの解説書でも出ないかな。
テンプレートスレ化しているなぁ。 ここでは役に立つ、役にたたないをあまり問わない方向で。 テンプレートといえば、テンプレートプログラミングが熱かった。 まったく役に立たないけど、そこそこいろいろなことが出来るよね。
638 :
デフォルトの名無しさん :03/09/26 00:05
#include<stdio.h> char read(char*); void write(char*); main() { char moji1[21]; read(moji1); write(moji1); } char read(char *x) { printf("文字を入れる!\n"); scanf("%s",x); return *x; } void write(char *x) { printf("%s",x); }
639 :
デフォルトの名無しさん :03/09/26 00:27
#include<stdio.h> char read(void); void write(char*); main() { write(read()); } char read(void) { char moji[21]; printf("文字を入れる!\n"); scanf("%s",moji); return *moji; } void write(char *x) { printf("%s",x); }
640 :
デフォルトの名無しさん :03/09/26 00:28
>>638 ・・・・で、このプログラムのどこがトリッキーなのか説明をお願いします。
641 :
デフォルトの名無しさん :03/09/26 00:29
>>639 moji[]はread()を抜けた時点で消滅するからアウト。
>>640 このスレが良スレの理由
・理解できないものには決して突っ込まない
・煽りや荒らしに一切反応しない
・sage進行
643 :
デフォルトの名無しさん :03/09/26 00:31
>>639 と思ったが、よく見るとこれ何?char *read()ならわかるが。
これの返り値をwrite(char *)で受けられるわけないだろ。
>>642 了解。多分ポインタ覚えたてホヤホヤで何か書き込みしたくて
仕方ない時期なんだろうと見た。
>>644 煽りもいれないように。空気のごとくスルーする事を期待。レス不要
システムコールと同名の関数でむりやり再帰させて何かしようとしてるのかと思ったが、 やっぱり訳分からん。
vector<int> v; v.push_back().... std::for_each( v.begin() , v.end, boost::bind(printf,"%d",_1));
>>636 例えば、Loki::SmartPtr は、StoragePolicy がテンプレートパラメータの
一番最後にきているけど、この技術を応用すると、StoragePolicy を
4つあるテンプレートパラメータのどこに書いても
きちんと StoragePolicy として継承するようになるわけだ。
SmartPtr< MyClass, MyStorage<_> > sp1;
SmartPtr< MyClass, MyOwnership<_>, MyStorage<_> > sp2;
SmartPtr< MyClass, MyConversion, MyStorage<_> > sp3;
( 「_」 は、継承時に、正しい型に置き換わる。ダミー )
で、実際にそれをやっちゃったのが、
http://www.cuj.com/documents/s=8890/cujexp0310alexandr/
>>648 目から鱗!
テンプレートによるポリシーの分割は後ろの方に持ってったポリシーのカスタマイズが面倒なのが欠点だったけど、
それだとStorageだけ自分で用意して後デフォルトが全部省略出来るってのはおいし過ぎ。
保守っと
期待sあげ
保守〜
ここは発言が無くなると一気に無くなるスレだな
静的フラグ。 struct Flag1{}; struct Flag2{}; struct Flag3{}; void foo( Flag1, int value ) { /* 処理1 */ } void foo( Flag2, int value ) { /* 処理2 */ } void foo( Flag3, int value ) { /* 処理3 */ } 使い方 foo( Flag1(), 12 );
>>656 トリッキーかどうかはともかく。
ttp://www.kmonos.net/alang/boost/classes/mpl.html のcreate_implが近いかも。
template<int no>
struct Flag{
enum{value=no};
};
void foo(const Flag<1> &,int value);
void foo(const Flag<2> &,int value);
void foo(const Flag<3> &,int value);
class Flag1Alias:public Flag<1>{};
typedef Flag<1> Flag1Alias2;
foo(Flag<1>(),12);
foo(Flag1Alias(),12);
foo(Flag1Alias2(),12);
というかLoki::Int2Typeでいいのでは、と思ったり。この場合。
まあ識別子名が使えるからいいかなと思うけど。
>>657 656だとtemplateを使わずにすむ、というよりCで出来るのが凄いのでは?
と書いて、演算子のオーバーロードはCでは出来ないことに気付いた。鬱。 しかし、テンプレートは処理系によっては使いづらいから、まぁ許して
struct static_cast_tag{}; struct dynamic_cast_tag{}; template< typename T > class smart_ptr { T * p_; ... template< typename U > smart_ptr( smart_ptr<U> const & rhs, static_cast_tag ) : p_( static_cast< T >( p ) ), ... {} template< typename U > smart_ptr( smart_ptr<U> const & rhs, dynamic_cast_tag ) : p_( dynamic_cast< T >( p ) ), ... {} ... }; template< typename T, typename S > smart_ptr< T > static_pointer_cast< smart_ptr< S > const & src ) { return smart_ptr< T >( src, static_cast_tag() ); } template< typename T, typename S > smart_ptr< T > dynamic_pointer_cast< smart_ptr< S > const & src ) { return smart_ptr< T >( src, dynamic_cast_tag() ); } Boost っぽく。
保守
最近いい感じに下がってきたね。 また地下でにぎわう良スレになりそうで嬉しい
if( (a && b) || (!a && c) ) ↓ if(a?b:c)
ModernC++DesignHosyu
会社でC++使ってるやついる?
>665 ふつーにみんな使いまくってると思うが。
665ではないが…
>>666 うちの会社は小規模なので、Lokiとかのtemplateをがりがり使っても
みんなついてきてくれるだけの技術を前提に出来るので平気なんだけど、
一般的な会社の場合はどの程度C++を使ってもいいのかな?
それと、C++を使った仕事ってどんなの?
うちはWindowsのクライアント開発(WTLベースなのとMFCベースなの)と、
組み込み系OSの開発に使っているけれど、最近Javaの方が多いな。
うちは組み込み系なのでC++はいまんとこ使ってない. スピード重視なんで抽象度を上げる方向には行かない. でもスピード重視じゃないやつに使ってやろうと,今何とか画策中.
>667 Winアプリ、組み込み(ネットワーク・カーナビ・医療・携帯) スレ違いなのでこの辺で。
>>665 クラス程度ならバシバシ使われてる。
ただtemplateまで使ってるのはほとんど見た事ない。
つーか漏れがほぼそのまま使えるサンプルを、vector使って1〜3日で書いたら、
設計と違うとの理由で却下し、設計通り配列使って1週間もかけて書いたりするし。
不定サイズのファイルを一括読み込みして処理するのに、それでええんかと。
>>670 いるいる。
そういう自分が書いたのはスバラシイのにって勘違いして
設計通り書けないヤシ。
スバラシイと思うなら設計を変えるよう努力シレ。
>>668 C++でスピードが犠牲になることってあるのかな?
アセンブラレベルまでカスタマイズが必要なら話は別だけど、
設計さえしっかりすれば組み込みでも十分威力を発揮できると思うけど。
>>670 671ほど口は悪くないが同意。正しいと思うことは主張するべし。
設計と違うコーディングをするのはどんな状況であれ言い訳できないかと。
>>669 まぁ、このスレは地下でマターリ技術的な話題で進行するスレだから
あながちスレ違いとも言えないかと
>672 仮想関数を使ったC++のコードであれば、 vtbl参照してアドレス解決するために仮想関数の呼び出し =関数のアドレス解決に単純に考えて1クロック余計に時間がかかる vtblを全く参照する必要のないコードであれば、 実行速度で差が出ることは普通ないと思う
>667 うちでLokiとか言っても誰もついてこないよ(泣 >672 うちはアセンブラレベルでカスタマったりしてるんでちと厳しい >設計さえしっかりすれば組み込みでも十分威力を発揮できると思うけど ですよね.スピードを追求するもの以外ならC++でいいと思うんだけど いやむしろC++で >674 どうせC++使うならvtbl使いたい.デザパタ使いたい.抽象度を高めたい. template使いたい.ジェネリックにしたい.トリッキーにしたい?(wじゃないですか C++のクラスを使ったbetterCでも悪くはないけど ということで啓蒙活動してます.次のプロジェクトあたりC++導入を... まあ組み込みでtemplateは厳しいが. ってことですれ違いなのでこのあたりで失礼します.Thanks>all
>>675 C++でテンプレート使ってもそれなりにタイトなコードを書けるのなら組み込みに使えるんでない?
演算子オーバーロードとインライン関数の組み合わせでCよりタイトに書けた例もあることだし。
テンプレートのインライン関数を使えば コンパイル時に解決できるコードであれば オーバーヘッドは無いんじゃないかな?
>>672 >設計と違うコーディングをするのはどんな状況であれ言い訳できないかと。
設計変更を提案するためのサンプルを組む時でもダメなのかと。
あと主張は一応した。
配列じゃバッファオーバーフローの危険があると説明したんだよ。
だが上司からは「客に設計見せたからもう変えられん。」と訳の分からん返答が。
それでも食い下がると、上司は諦めたのか客に電話をし始めた。
しかし会話を聞いてると、なぜか扱うファイルの最大サイズなんぞを質問してやがる。
そして電話を切った上司はにっこりと、「バッファオーバーフローの心配は不要だ。」
('A`)
…スレ違いなのでここまでにしとく。
後は好きに想像してくれ。
もちろん漏れを厨扱いするのも自由だ。
>>678 なるほど670は「設計に異議あり」というコードだったのか。
その却下の理由が「設計と違う」って意味不明だな
すれちがいだから俺もここまで
>>678 bufferOverflowして何か不具合が出た場合、全ての責任は上司が被る事にしないとマズイよ
>>678 あのね、お客と仕様を決めてしまったものに対して
おいそれと勝手に変更することは出来ないの。
もう少し大人になれ!
どうして、設計通りじゃだめで書いたサンプルがいいか
お客に説明して納得してもらわなければ主張したとは言わないの。
がんばれ!
上司の中の人の挙動からは仕様が「配列で実装する」という内容だとはとても思えないんだが…。
そろそろスレ違い気味だからスルーして、C++の話題に戻ろうと言ってみたり で、インライン展開されるC++コードならばvtblの影響も受けないわけで、 うまく設計すれば呼び出しオーバーヘッドもなくすことが出来るのでは? もっともよほどうまく設計して、コンパイル時にほとんどすべてが計算できるような 複雑なテンプレートを必要とするだろうから、一般企業では向かないと思うけど。
>>683 コンパイラがインライン展開してくれたり、オーバーヘッドの
少ないバイナリを吐いてくれる保証など無い。
どーいうコードに対しどーいうバイナリ吐くか分ってるコンパイラで、
そのコンパイラに特化したコードを書くのなら保証はあるだろうが、
アセンブラの知識が必要だし、だったらアセンブラで直接書いた方が
早いのではなかろーか。
#それでもあえてC++で書けば、このスレに相応しいコードになるかも知れんが。
>683 vtbl使わず、再帰テンプレートやインライン展開させる目的で テンプレートを使うのは有効だと思うよ ただ、やっぱり仕事で使うのはチームのテンプレートに対する知識レベルや 後々のこと考えると難しいんじゃないかな あと、テンプレートの痛いとこはコンパイラによって 激しく対応が異なる場合があるのがね・・ >684 煽りですか?
ぶっちゃけ、C++の話もスレ違いだと重いマース。別に俺は動でもいいけど。
>>684 C++についてはもう少し勉強したほうがいいね。
アセンブラできちんと管理できるプロジェクトであれば、アセンブラでやればいいんじゃない?
>>687 何を勉強しろと。
インライン化やテンプレートの使用によって、
>>683 の期待通りの効果が
あるかどうかはコンパイラ次第でしょ。
まぁ最近のコンパイラなら、普通の期待には答えてくれるだろけど、
アセンブラレベルでカスタマってるようなヤシの期待に答えられるとは思わんね。
あおりはスルーの方向で。せっかくの良スレなんだから。 #内容的には面白いんだが続けると荒れそう
深度500超というのもあるな。
みんな gcc でもインラインアセンブラ使う? 漏れ gas の文法が今ひとつわかんなくて。。 せっかくの煽りだから関連したネタ持ち出すんだけど、昔 EPOC32、今 Symbian OS って いう ARM OS で携帯電話や PDA 向けのがあるんだけど、これは API が全部 C++。 Cygnus で Win32 なんかでクロス開発する。 一方、非常に COM っぽい感じの携帯電話AP開発用の BREW ってな規格の方は、 なぜか gcc で hoge->aho(a) みたいなのを Hoge_Aho(hoge, a) って書かないとダメ。 開発元の Qualcomm はそのうち g++ 使えるようにします、って言ってるんだけど。 大企業なんだから、おとなしく Cygnus にお金払って開発環境整備すればいいのに。。
例えばさ、Modern C++ Design に出てきたファンクタを使って int func1( int val ) { return val; } // int ( int ) な関数 ... Loki::Functor< void, TYPELIST_1( int ) > fun( &func1 ); などとしようモノならば、fun(12); などとやった時点でコンパイルエラーが 起きるわけだけれど、VC++ 7.1 ならば、 template< typename R > structretval { template< typename T > static R r( T val ) { return val; } }; template<> struct retval< void > { typedef void r; }; みたいなモノを用意して、FunctorHandler の operator() の内容を、 ResultType operator()( ... ) { return retval< result_type >::r( f_( ... ) ); } と書き換えてやるだけで、boost::function でいうところの互換性のある ファンクタが実現できる。つまり、int func( long ) な関数を、 Functor< void, TYPELIST_1( short ) > に渡して、実行することができるわけだ。
いろいろ変なところがあるなぁ。 つーか、retval クラスは、 template< typename R > struct retval{ typedef R r; }; だけでよさそうだ。
>>694-695 追記。VC++ では以下のコードが普通に通るので、
>>694-695 のような変なことをしなくてもいいらしい。
int show_int( int val ) { std::cout << val << std::endl; return val; }
template< typename T > void call( T fn )
{
return void( fn( 10 ) ); // !
}
int main() { func( show_int ); return 0; }
VCの場合はバージョンを書いてくれると嬉しい。 多分VC++7.1だと思うけど。 買うかなぁ、VC
あけましておめでとう
>>608 デバッガ無しだと例外が投げられるが
デバッガが付いてるとデバッガに落ちる(例外は投げられない)
>>700 ?
意味分からんというから説明しただけだが
3ヶ月も前にレスに説明ですか
703 :
デフォルトの名無しさん :04/01/06 05:12
if(*/*/**/"*/"/*/**/"*/") { /* コメントをネストできない場合 */ } else { /* コメントをネストできる場合 */ }
bool bAllowNestedComment = !*/*/**/"*/"/*/**/"*/";
昔なんかの本で見た。 int i; /* */ printf("%c", i["test"]); 既出?
>>702 今年になって発見したんだからしょうがないじゃんかよう
間違ってた...。 こっちが本命。 if(/*/*/0*/**/1) { /* ネストがあるとき */ } else { /* ネストが無いとき */ }
>>708 コンパイラ警告対策で、マクロ化したくなるなー。
#if /*/*/0*/**/1
#define HAVE_NESTED_COMMENT 1
#endif
#if HAVE_NESTED_COMMENT
/* ネストがあるとき */
#else
/* ネストが無いとき */
#endif
CHoge ...; ........=.......(........);
main() { puts("ラデツキー"); return 0; }
/* procedure.h */ _PP_CLASS_NAME() { ... } _PP_CLASS_NAME & operator=( _PP_CLASS_NAME const & rhs ){ ... } ... /* いろいろな共通関数とか */ ----------------------------------------- /* classes.h */ class myclass_1 { #define _PP_CLASS_NAME myclass_1 #include "procedure.h" #undef _PP_CLASS_NAME ... }; class myclass_2 { #define _PP_CLASS_NAME myclass_2 #include "procedure.h" #undef _PP_CLASS_NAME ... };
>>714 interface + mix-in の強力さを知れば
君も気が変わるだろう。
>>712 これ面白いね。低級な記述で mix-in ベースの OO ができる。
デバイスドライバとか書くときに使えそう。
#define PROCEDURE(classname) \ classname() { ... } \ classname & operator=(classname const & rhs){ ... }\ .../* いろいろな共通関数とか */ \ /**/ class myclass { PROCEDURE(myclass) ... }; これでも同じだよな?
同じだな。
むしろ数段マシじゃないか?
>>717 マナー的には数段マシだけど、実用的には何十行も \ つけるの面倒なのと、
デバッグ時に欝になること必須なのがまずそう。。
PROCEDURE が全部一行に展開されちゃうもんな...。 エラー行が全部一緒になるぜ(w
>>712 の手法は、boost::bind で利用されてるな。
なかなかおもしろいから、一度読んでおくといいかも。
>>712 は、templateを使うのと比べてどう便利なの?
あとmix-inって簡単に言うとどんなの?
>>724 実装を継承するんじゃなくて、埋め込む。
インターフェイス以外の多重継承を回避しつつ
実装を使いまわしたいときに有効。
>>712 突き詰めるならboost/preprocessorという手もあるよ。
あれだと数値とか変数扱えるし。
BOOST_PP_WHILEのようにループもあったし。ループというよりstlのfor_eachのように関数渡すような感じだが。
プリプロセッサのみなんでたぶんCからでも使える
>>725 説明ありがとう。そこそこ理解できたけど、まだちょっとわからないな・・・
templateでは出来なくてmix-inだと出来る場面ってどういうのだろう?
マジレスすると、mix-in っていうのはテンプレートと対立する概念ではなくて、 たとえば Microsoft の ATL なんかでは template を使って mix-in を実現している。 template なしの普通の多重継承でも mix-in は実現できなくもないけど、 あらかじめアレコレ virtual にしておかなきゃならない辺りが絶望的にドンくさい。
うーむ、ちゃんと調べたほうがよさそうですね。 いろいろと教えてくれてありがとう
Ruby でも使ってみれ。
//A.cpp #include "B.h" class A { void hogeA(){ pB->hoge(); }; void hoge(){}; protected: B *pB; } //B.cpp #include "A.h" class B { void hogeB(){ pA->hoge(); } void hoge(){}; A *pA; } 見たいなのを上手いことコンパイルするにはどうしたらいいでしょうか? *注* コンストラクタ、デストラクタ、 pA,pBを設定する部分については省略しています
A.h/B.hにはなにが書いてあるんだ? A::pBだけprotectedになっている意味は? セミコロン不足してない? > 見たいなのを コードで語れないなら、せめて日本語でちゃんと書けよ。
.h じゃなくて、.cpp にしてみたらとうなるんじゃろ。
>>732 の
//A.cpp
と
//B.cppの部分は両方とも .h の間違いです。
すいません
言いたかったのは
2つのクラスがあってお互いがお互いのポインタを持つ
という関係をどうやったら書けるかということです
乱筆ですいませんでした。
class B; class A { B *p; } ・・・何故このスレなんだ?
>>736 ためしに書いてみたら
void classA::hogeA()
{
pB->hoge();
};
のところでエラーが出ますた。
// A_fwd.h class A; // B_fwd.h class B; // A.h #include "A_fwd.h" #include "B_fwd.h" class A { void hogeA(); void hoge() {} protected: B *pb; }; // B.h #include "A_fwd.h" #include "B_fwd.h" class B { void hogeB(); void hoge() {} A *pA; }; // A.cpp #include "A.h" void A::hogeA() {pB->hoge();} // B.cpp #include "B.h" void B::hogeB() {pA->hoge();}
お互いの依存関係は明らかなんだからこうじゃないのか? // A.h class B; class A { public: void hogeA(); void hoge() {} protected: B *pB; }; // B.h class A; class B { public: void hogeB(); void hoge() {} protected: A *pA; }; // A.cpp #include "A.h" #include "B.h" void A::hogeA() { pB->hogeB(); } // B.cpp #include "B.h" #include "A.h" void B::hogeB() { pA->hoge();}
inline指定して外に出すしかないでしょ。 AとBを別のヘッダで定義してるなら それぞれinline-impl.hが必要かもね。
// A.h class B; class A { public: void hogeA(); void hoge() { } protected: B *pB; }; #include "B.h" inline void A::hogeA() { pB->hogeB(); } // B.h class A; class B { public: void hogeB(); void hoge() { } protected: A *pA; }; #include "A.h" inline void B::hogeB() { pA->hogeB(); }
ちょっと趣旨違うけど トリッキーな結果になるプログラム。 long main(long argc, char **argv) { long i; double x1,x2,x3,x; x = atof(argv[1]); if (x <= 0.0 || x >= 1.0) return 0; x1 = x - 0.000001; x2 = x; x3 = x + 0.000001; for (i=0; i<=100; i++) { x1 = A * x1 *(1 - x1); x2 = A * x2 *(1 - x2); x3 = A * x3 *(1 - x3); printf("%12.10f %12.10f %12.10f\n", x1, x2, x3); } return 0; } これ↑を0〜1の範囲の数値をパラメータにして実行してみて。 (ただし0.5、0.25、0.125等はつまらん結果になるので0.3とか0.6あたりで。) で、Aの定義を3.2、3.5でも試してみて、次に3.8にしたときにどうなるか予想した上で A=3.8で実行してみて。 カラクリ知らないとこの結果は結構ビックリすると思います。
ごめん。肝心なもの忘れてた。
>>742 の最初の方に↓入れといて。
const double A = 2.8;
//const double A = 3.2;
//const double A = 3.5;
//const double A = 3.8;
>>742 ニュートン法かオイラー法に相当するのかなあ。
実行してないけど、数値誤差だろ? どうせ。
実行してないけど、カオスじゃないの? 初期値の違いで結果が大きく変わるって言うような。
確かにその可能性もあるな。
VBで小ネタですけど [必要ページ数] = -Int(-( [全行数] / [ページ内行数] ))
>>749 VBのIntって常に負の無限大方向への丸め?
小ネタ perl -pi.bak -e 's/aaa/bbb/g' *.cpp 他言語やシェルで同じこと1行でできるかな?
>>751 最近のFreeBSDやRedHat Linuxとかのsedなら
sed -i.bak -e 's/aaa/bbb/g' *.cpp
でOK
Boost.Bind を javascript に移植したものらしい。
http://www.cppll.jp/upload/sid=40/bind.lzh function fun( a, b, c ) { return a + b + c; }
bind( fun, _1, _2, 10 )( 1, 2 ) // = 13
bind( fun, _1, _1, _1 )( 100 ) // = 300
bind( fun, _4, _3, _5 )( 1, 2, 3, 4, 5 ) // = 12
>>753 ためしてみたけど、組み込みオブジェクトのメソッドはだめだね。
ユーザ定義オブジェクトのメソッドはOKっぽい
function proxy_str( s )
{
this.replace = function( e, r ){ return s.replace( e, r ); }
}
bind( new proxy_str("test ok?").replace, /\?/, _1 )( "!" ); // = "test ok!"
Boost関連でいいドキュメントってどこらへん? スレ違い気味すまそ
758 :
デフォルトの名無しさん :04/04/22 16:13
va_list を返す関数とかって、なんとかして作れませんか? メモリを割り当てて全部va_listの内容をコピーとか出来ればいいんだろうけど。
>>758 va_list は大抵、単なるポインタなんだけど…
>>728 あったあった。ATL学習する時、忌々しい思いをして読んでいた。
プリプロとテンプレートの集合体で場合分けの塊って感じだったな。
>>758 va_listの生成自体が定義されてないから無理。
そもそも本当にva_listである必要があるのか?
template< class Derived > class hoge_impl { friend Derived; hoge_impl() { ... } hoge_impl( int val ) { ... } int do_1() { ... } int do_2() { ... } }; class hoge : public hoge_impl< hoge > { hoge() : hoge_impl(){} hoge( int val ) : hoge_impl( val ){} int do() { return hoge_impl::do_1(); } }; まぁ、一種の mixin と言えない事も無い
間違えた。 下の class hoge は、struct hoge に変換して。
Hackers' Delight に載ってるビットカウントアルゴリズムの話題はがいしゅつ?
ビットの左右反転ってこんな感じだっけ? unsigned int bitreverse(unsigned int n) { n = ((n & 0x55555555) << 1) | ((n >> 1) & 0x55555555) ; n = ((n & 0x33333333) << 2) | ((n >> 2) & 0x33333333) ; n = ((n & 0x0F0F0F0F) << 4) | ((n >> 4) & 0x0F0F0F0F) ; n = ((n & 0x00FF00FF) << 8) | ((n >> 8) & 0x00FF00FF) ; return (n << 16) | (n >> 16) ; }
単項関数を二つつなげて、2項関数にする。 template< typename L, typename R > struct 2uni_to_bin { 2uni_to_bin( L l, R r ) : l_(l), r_(r) {} template< typename A1, typename A2 > void operator()( A1 a1, A2 a2 ) { l_( a1 ); r_( a2 ); } L l_; R r_; };
Boostの関数型プログラミングはかなりトリッキー
そうか? 関数型プログラミングは気持ちいいぞ
//* テストコード1 /*/ テストコード2 //*/ このままだとテストコード2がコメントアウトされ、 最初のコメント行を /* に変えるとテストコード1がコメントアウト。 #ifdefを使うべきだけど、エディタで色変わんないからテスト中紛らわしい。
会社で使ってる構造化エディタは#ifdefマクロ折り畳みできるからな
772 :
デフォルトの名無しさん :04/06/28 18:58
ほっしゅ
773 :
デフォルトの名無しさん :04/06/29 01:01
ビッグエンディアン リトルエンディアン 判定 int x = 1; x = *(char*)&x; // 0:ビッグエンディアン/1:リトルエンディアン
774 :
デフォルトの名無しさん :04/07/14 00:44
0==0
(0==0)
(a^o^a) ==3
華麗に777げと
VB6やってた頃、 x = y = z if x then て書いたら嫌われた トリッキーじゃないのに
>778 Cやってる人から見ると嫌だなw
>780 その方が危ないような気が。
>779 C++メインでやってるけど別に普通だと思うんだが、どのへんが嫌? >781 禿同。 結合規則くらいは覚えておけ、と。
VB的には if( y == z ){ x = TRUE }else{ x = FALSE } if( x ){ … なコードなんだけど、C/C++だと y = z; x = y; なコードっぽくて気持ち悪いでしょ? 演算子の優先順位があっても括弧を付けるのがスマートなコードだと思ってるんだけど。
>>783 >演算子の優先順位があっても括弧を付けるのがスマートなコード
x = ( y = z );
((((1+2)+3)+4)+5)+6
オレが悪かった 頭丸めて修行の旅にでてくる
すぐ極端に走る三流PGが 意気揚々と揚げ足取り
b = a + (a=b)*0; a,bの入れ替え。こんなのどうでしょう。
未定義じゃないよ不定だよ。
ごめんなさい未定義でした。
a ^= b ^= a ^= b; a,bの入れ替え。こんなのどうでしょう。
奥村本にも載ってるなぁ
a ^= a^= a^= a; なんて使い方しなければ、整数相手なら問題ないけどな 遅いけど
だから未定義なんだって。
xorについては
>>106 と
>>129 からの話を参照。
速くはないけど決して遅いという訳では。
俺は楽に書けるという理由でよく使う。
>797 読んでみたけど、「変数はスタックに置かれる」という前提が スッポリと抜けて議論されてるのに少し違和感を覚えた。 mov eax, [esp+n] mov ebx, [esp+m] mov [esp+m], eax mov [esp+n], ebx こうかな?
もう十月だ、保守
つ800
sageで保守?
803 :
デフォルトの名無しさん :04/11/24 12:26:55
書き込み期待age
804 :
デフォルトの名無しさん :04/11/24 14:30:25
代入において、ary[10] と 10[ary]は同じである。(宣言では後者はだめ) char ary[10]; 5[ary]=100; /* 普通の書き方 ary[5]=100; */ printf("%d\n", 5[ary]);
タダの言語仕様じゃん
三項演算子使えばトリッキーに見える
>>804 それは
for (int i=0; i<10; i++)
printf("%c", i["abcdefghij"]);
みたいな有名なコードがあるじゃないか
VBで 文字列を入力すると、その文字列が回文(右から読んでも左から読んでも一緒) であるかどうかを判別するプログラムのコードだれかわかりませんか?
s = gets puts s == s.reverse
811 :
デフォルトの名無しさん :04/11/24 16:07:14
std::list<CClass> obj; std::list<CClass>::iterator it=obj.begin(); CClass *pClass = &(*it);
812 :
デフォルトの名無しさん :04/11/24 16:56:31
printf("%s:%p\n", "printf", printf);
>>798 変数をスタックに確保することを前提としていることに違和感を覚えた。
インラインアセンブラとかの話かな?
それにしたってルーチンの入り口と出口以外では可能な限りレジスタを使いまわすものだよ。
>798,>813-814 前スレ読んでから出直して来い。
intを2進数変換して表示するコードどうやる?
int型の変数の値を2進表現で出力するってこと?
std::cout << std::bitset< std::numeric_limit< int >::digits >( n )
821 :
デフォルトの名無しさん :05/02/27 23:15:18
晒しage
int main(void){main()}
823 :
デフォルトの名無しさん :2005/04/03(日) 21:47:03
大してトリッキーでもないが配列も初期化できる擬似new #include<stdlib> class New { void *p;size_t sizel,size; public: template<class type> New(type value) { p = malloc(sizeof(type)); (*(type*)p) = value; size = sizeof(type); } template<class type> operator type*() { type *damy = (type*)malloc(sizel),*copy = damy; do*damy++ = *(type*)p;while(0 < (sizel -= size)); free(p); return copy; } New &operator [](unsigned size) { sizel = New::size * size; return *this; } }; class demo{int value;public:demo(Value):value(Value){}int out(){return value;}}; int main() { demo *ary = New(demo(20))[8]; delete ary; }
それdeleteしたらまずいんじゃない?
825 :
823 :2005/04/03(日) 22:17:29
>>824 いやべつに
それと、#define new New
としとくとなおエレガント
>>825 mallocしたものをdeleteしていいのかとか、
char *ary = New(demo(20))[8]; が普通にできてしまうがいいのかとか、
damyってのはどうなのかとか、いろいろあるのだが、
そもそもVC++でもg++でもコンパイルが通らないのだが。
>>825 わかって書いてんのかな…。
>#define new New
そりは最悪なんでやめてくだしあ。
>>823 お前C++をちゃんと勉強すれ
>(*(type*)p) = value;
クラッシュする
>do*damy++ = *(type*)p;while(0 < (sizel -= size));
同様にここも
>いやべつに
全然「べつに」じゃねーよ。deleteしたらマズイ
>それと、#define new New
>としとくとなおエレガント
どこがや。
new int;
ってコードもかけなくなるウンコ手法じゃねーか
>>826 newの中でmalloc使われてるんだけどねぇ。
(callocだっけまぁいいや…。)
830 :
823 :2005/04/03(日) 22:50:40
>>828 どこがや。
new int;
ってコードもかけなくなるウンコ手法じゃねーか。
ネタのつもりだったが…。
ああそうなんだ。 >823のコードがあまりにアレなんで本気にしちゃったよ。 ごめんね。
>>(*(type*)p) = value; >クラッシュする この場合、テンプレート展開?後の状態にすると p = malloc(sizel);//4バイトメモリーを確保 (*(demo*)p) = value;// demo型にdemo型を代入しているしだけなんだがなぜ? (まともにコピーコンストラクタを設定してなかったらするかもしれないが…。) >>そもそもVC++でもg++でもコンパイルが通らないのだが。 VC++持ってないんだけど、どんなエラー出るのかキボンヌ。 (もしかすると、行が多すぎたんで添削したせいかも。)
>>829 いつの間にそういう規格になったの?
そのような実装もあるという話ではないのか?
835 :
デフォルトの名無しさん :2005/04/03(日) 23:24:02
>>833 > (まともにコピーコンストラクタを設定してなかったらするかもしれないが…。)
逆。まともなコピーコンストラクタがあればクラッシュする
可能性が高い。
> VC++持ってないんだけど、どんなエラー出るのかキボンヌ。
New::operator [] が曖昧。
>そのような実装もあるという話ではないのか? スマン見落とした。
>>836 エラー報告tenx。
やっぱり処理系によるんだろうねぇ。
>>833 >>836 コピーコンストラクタは>823のコードでは一切呼ばれない
>(*(type*)p) = value;
これだとコンストラクタも何も呼ばれてない状態なのにいきなり代入演算子が呼ばれる。
指定したメモリ上でオブジェクトをコンストラクトするには、次のように配置newを使う
p=malloc(sizel)
new(p) demo(value);
それとdeleteは最初のオブジェクト以外のデストラクタが呼ばれない欠陥もある。
>823を改良するとこうなる #include<vector> class demo{int value;public:demo(Value):value(Value){}int out(){return value;}}; int main() { std::vector<demo> array(8,demo(20)); }
>>839 >コピーコンストラクタは>823のコードでは一切呼ばれない
ホンとだ、何でだろ?
何でって…。 damy,tenxからして全てネタ?
>>841 >tenxからして全てネタ?
Thankからthanxと打ったつもりだったんだけど、疲れかな…。
それから、damyはdummyのことじゃないよ。個人的なfoo見たいなもん。
コピーコンストラクタが呼ばれる書式しってる?
というか「コンストラクタ」の意味を考えれ。
>>823 は「C++」を勉強しなおす必要があるとわかっただけでももうけものじゃないかな。
LISP CONSでぐぐれ
>>566 すげー遅レス&すれ違いだが、凄く感心したので使ってみた。
で、ググってみた。
VS.NETで確認したんだけど
// TODO ほにゃらら
ってコメント書けば、普通に「タスク一覧」に表示されるのな orz
便利になったもんだ
#pragma mark ってあったな確か。
848 :
デフォルトの名無しさん :2005/04/29(金) 00:18:51
トリッキーってのとはちょっと違うけど、 int is_sip_message( const char* buf ) { return *(uint64_t*)buf == *(uint64_t*)"SIP/2.0 "; } これってアリ?普通?常套手段?
スマン、何がしたいんだかわからん
レジスタで文字列を一発コピーしたいとか、そういう 最適化の類いじゃないのか?
アライメントが考慮されてねぇじゃん糞
アラインメントは関係ない気がするが。
>>848 普通。
関係ある。俺の環境ではコケる。
アライメントが厳しい環境を考慮するとダメ。
intel以外脳内削除すればOK
856 :
デフォルトの名無しさん :2005/04/30(土) 13:51:26
「個人的なfoo」って言う表現がいい じゃあ、おれも個人的なtinpoとかmankouとか使いたい 月曜の朝一、コード規約にかいとけよ
月曜もお休みです 残念
858 :
デフォルトの名無しさん :2005/04/30(土) 14:28:07
#define FOO main typedef int HARDGAY ;
860 :
デフォルトの名無しさん :2005/04/30(土) 22:40:28
イジザ ハ〜ゲ〜ズナイツ♪ イギナワクゥン〜ベルホ〜オ〜♪
月曜は暴落しそうだから や
862 :
デフォルトの名無しさん :2005/05/01(日) 10:06:06
int main(int argc, char* argv[]) { int a=10,b=7; printf("割ってかける演算子、かけて割る演算子\n"); // 3で割ってから3でかける演算子 a/*=3; // 5でかけてから5で割る演算子 b*/=9; printf("a=%d b=%d\n",a,b); getchar(); return 0; }
>>862 コメント
トリッキーっていうか、
コメントで嘘ついてるだけじゃねーか
まあ普通にポインタ同士を割り算しようとした俺には通用しない技だな
865 :
デフォルトの名無しさん :2005/05/01(日) 13:15:45
3時間も考えて出した答えがそれかい?
>>865 いや、俺のときは丸2日悩んだよ
気付いたときはプログラマ辞めようかと思った
867 :
:2005/05/01(日) 13:25:18
868 :
デフォルトの名無しさん :2005/05/01(日) 13:29:10
おれは、getchar(); って書いている時点で Windowsでやってるのかな?ということぐらいしかおもいつかんかった
ほしゅ
>>862 今更だけど。面白い。
コメント色分けするエディタに貼るまで気付けなかった……。
>>863 を見てすら意味が分からんかった俺って一体。orz
func: MOV @R6+,R5L BEQ ?0001 JSR func INC R6 RTS ?0001: SUB R6,R6 RTS これは何をする関数でしょう?
すんません、INC R6 の行がよけいでした。 func: MOV @R6+,R5L BNE func ?0001: SUB R6,R6 RTS これでいいかな?
やっぱり872は間違ってるなorz 871のほうでお願い。
>>871 R6で与えられた位置から最初にゼロが見つかるまでの個数を
スタックがその深さあるならR6で返すみたいね。
素直に、
func:
PUSH R6
?0001:
MOV @R6+,R5L
BNE ?0001
POP R5
SUB R5,R6
RTS
みたいに書いた方が短いし、実行速度も早いし、
よくお判りで。これ、大昔の「bit」ってマニアックな雑誌に載ってた演習問題だったの。 strlen()関数をこともあろうに再帰で実現するというアホらしい手法に呆れたので覚えてた。
876 :
デフォルトの名無しさん :2005/07/12(火) 10:38:40
void papaguma(^−^)
それはコンパイル通らないぞ
h
879 :
デフォルトの名無しさん :2006/01/05(木) 19:18:09
public class Hoge { public static void main(String[] args) { if (0 == args.length) { // 処理 } } }
#define ` ' if( ( 'A`)<mandokuse ){...} とかしようとしたら普通にゴルァされた('A')
main(){char*a;printf(a,34,a="main(){char*a;printf(a,34,a=%c%s%c,34);}",34);}
硬いこといわない('・ω・`) main(){char*a="main(){char*a=%c%s%c;printf(a,34,a,34);}";printf(a,34,a,34);}
34てのは環境依存かなー。
そのとおりだなー。 世の中全てがASCIIとは限らないんだなー。
for (unsigned char i=0x01; i>0x00; i++) なんか気持ち悪い
win32gui のイベントハンドラの登録方法がトリッキー。
ttp://kmkz.jp/mtm/?day=20050117 サインテーブルジェネレータだって
int cos_table[1024] = {1<<24,16776900};
void build_table() {
__int64 a;
int b;
a = b = cos_table[1];
for( int i=2;i<1024;i++ )
cos_table[i] = b = ((a*b)
>>23 ) - cos_table[i-2];
}
>>890 きっとそこがトリッキーなんだよ!!
な、なんだtt
それほどトリッキーでもないかも知れんが。 int a[100]; for(i=0;i<sizeof(a)/sizeof(a[0]);i++) { ... }
可読性を美しく損なえばトリッキーになるはずだ
他人に変な顔されたコード。トリッキーか? // 整数→文字列変換 const char* convert( int id ) { const char* p = ""; switch( id ){ case HOGE: p="hoge"; break; case MOGE: p="moge"; break; : } return p; }
トリッキーというより単に冗長なコードだから変に思われたんじゃないの? 俺ならこう書くけど。 enum{HOGE,MOGE,HOGE_MAX}; const char* convert( unsigned id ){ static const char*id_txt[HOGE_MAX]={"hoge","moge"}; return id < HOGE_MAX ? id_txt[id] : ""; }
頭悪いっつーより 別ファイルから読むかヘッダで定義したい。すげー気持ち悪い。
>>892 >sizeof(a)/sizeof(a[0])
C標準でマクロ定義されていないのが不思議なほど
スタンダード。
>>894 文字列ベタ書きでいいなら
何の問題もない。
問題ありすぎ。 そんなわけのわからんマジックコードとの変換がソース中に散らばってたら 三日前の自分に対してでも殺意を抱く
>>899 C/C++ で enum から文字列への変換はどう書いてるの?
毎回 def ファイルみたいなの用意すんの?
連想配列作るとか
>>900 elements.txt
HOGE, HAGE, HIGE
hoge.h
enum{
#include "elements.txt"
}
hoge.c
const char *hoge[] = {
#include "elements.txt"
}
>>894 それって実行するたびにメモリが1byteずつ漏れない?
>>903 リークはないが、処理系によってはひどいことになる。
>>903 はぁ?なんでそう思ったんだ?
>>904 どんなひどいことか、具体的に言ってみ。どうせ言えない知ったか乙
>>902 …コンパイルできないその糞コードをどうしろと?
>>902 スレ趣旨からすると
elements.txt
VAL(HOGE), VAL(HAGE), VAL(HIGE)
hoge.h
#define VAL(v) v
enum {
#include "elements.txt"
};
#undef VAL
hoge.c
#define VAL(v) #v
const char* hoge[] = {
#include "elements.txt"
};
#undef VAL
>>903 もう帰ってくれ。
>>895 まだまだだな。
return id < HOGE_MAX? "hoge\0moge"[id*5]: "";
文字列の長さが違ったらどうすんだよ
そりゃ一番長いのに合わせるに決まってるじゃないですか。 return id < HOGE_MAX? "hogehoge\0moge\0\0\0\0"[id*9]: "";
はい、糞テクニック認定。一々文字列の長さなんか数えてられるか。
912 :
910 :2006/02/28(火) 19:35:25
(´-`).。oO(マジレスされちゃった…のかな?)
913 :
911 :2006/02/28(火) 19:45:14
(´-`).。oO(うわ…マジレスされた)
>895 idはintだから、負値が放り込まれたら… あと ・idが連番じゃないケース ・idに負値があるケース ・idを追加削除する時の手間 も考えませう。
915 :
910 :2006/03/01(水) 02:33:57
>>914 >idはintだから、負値が放り込まれたら…
idはunsingedにしてあるだろアホ!
>あと
>・idが連番じゃないケース
>・idに負値があるケース
>・idを追加削除する時の手間
>も考えませう。
何小学校の先生ヅラしてんだお前?
どっちかっつーと、生徒はお前の方だ。お前が考えろボケ!
どうせお前の脳味噌じゃ思いつかないだろうがな。
>>915 生徒に話しかける時はもっと優しく語りかけてやれよw
つーか実装の問題。 それを何に使ってるか、全体が何をしたいのか、によるから一概には言えない。 例えば負数が与えられる可能性について考慮してないコードであっても 絶対に負数が与えられないならば それは最適化された良いプログラムと言えるし 逆に、ループ最深部で鬼のように呼ばれるのに 負数チェックをしているようであればそのコーダを無能と言わざるを得ない。 最適化を考えるなら関数コールなんてアホの極みという意見もあるし 他の非ループ場所からも呼ばれる上にインライン展開されるから問題ないので 可読性や保守性との兼ね合いでそうしてるという可能性もある 結論として、一概には言えない。
918 :
910 :2006/03/01(水) 13:07:03
(´-`).。oO(辻希美ちゃんは可愛いなな・・・)
(´-`).。oO(miyuタンは今どうしてるだろ…
921 :
914 :2006/03/01(水) 23:20:22
>915 >idはunsingedにしてあるだろアホ! 寝ぼけてた。orz あと諭すような書き方したのは、>894の冗長さの意味も考えては? っつーのをやんわり指摘したかっただけなんだ。 >914に挙げた点を考慮すれば、それなりに妥当なコードだと 思うんだが。
仕様として id に負数が含まれることがあるなら unsigned にしたとこで解決はしないけど。 まあ言ったらきりないし。
>>922 負数なんぞ適当に算術演算して正数の範囲に収まるように変形すれば良いだけ
負数が含まれているのなら
id+HOGE_MIN <= HOGE_MAX-HOGE_MIN ? id_txt[id+HOGE_MIN] : "";
にすれば良いだろ(idは当然unsigned型)。
#define NUMOF(a) (sizeof(a)/sizeof((a)[0])) char *p = ""; if(( -NUMOF(id_txt1)<id )&&( id<NUMOF(id_txt2) )) p = id<0 ? id_txt1[-id]: id_txt2[id]; idの型をenumにすれば、if文をassertで置き換えても 良いんじゃないだろうか。
またうんコードの投稿ありました
>925 何の何処がどうウンコなのかきちんと説明してくれないと どう反応すりゃいいのか分かりません。 #スレのお題がお題だけに、全部糞といえば糞だしねぇ。
けちつけまくってるわりに894より素直で汎用性の高いコードが 出てこない件について。 数が多ければ907だろうけど。 というか894は文字列定数を返したから変な顔をされたという、 低レベルな話ではないだろうか。
>>927 >出てこない件について。
スレタイ100回音読の刑
誰か各整数型(signed|unsigned)(char|short|int|long long) を引数にとってその最大値を返すマクロ書いて。
C++なら numeric_limits<TYPE>::max() で済むんだがなあ これじゃあトリッキーでも何でもないよな
limits.hで各整数型の最大値・最小値がマクロ定義されてるが それではダメなんか?
#define max(T) (((T)(-1)<0)?(((unsigned long long)(-1)>>(65-sizeof(T)*8))):((T)((unsigned long long)(-1))) ) こんなんできましたけどー。
charはchar型で返してしまうが、それが嫌ならもう一段三項演算を追加するけども。
>(65-sizeof(T)*8) ウンコ
トリッキーなんだからこれぐらいの方がいいだろ('∀`) 嫌ならちゃんとlimits.hかなんかを使いなさい。
#define TYPE(type) ((type) -1 > 0 ? (type) -1 : (type) -1 ^ (type) ((type) 1 << (sizeof(type) * CHAR_BIT - 1)))
CHAR_BIT使うぐらいならlimits.h使うだろ……('д`;)
でも綺麗にかけてるよ、負けた(・ω・`)
TYPE_MAX(unsigned long) が ULONG_MAX に展開されるようなマクロを頑張って書いた俺は莫迦だったのか…
賢くはないな
でもそっちのほうがトリッキーだとは思うよ。
トリッキーでもないな
944 :
936 :2006/04/04(火) 19:52:59
#define TYPE(type) ((type)~((type)((type) -1 < 0) << (sizeof(type) * CHAR_BIT - 1))) でもいいね。まあ即値ならなんでもいいと思うけど。
>>943 一レスに収まらないので分割で。
# define CAT_I(x, y) x ## y
# define CAT(x, y) CAT_I(x, y)
# define IF(c) CAT_I(IF_, c)
# define IF_true(t, _) t
# define IF_false(_, f) f
# define PREFIX_IF(c, p, b) IF(c)(CAT_I(p, b), b)
# define SEP(f, a) f a
/* トークン取得 */
# define TOK(ts) (CAT_I(TOK_, ts))
# define TOK_signed signed, false,
# define TOK_unsigned unsigned, false,
# define TOK_char char, false,
# define TOK_short short, false,
# define TOK_int int, false,
# define TOK_long long, false,
# define TOK_END !, true, !
# define IS_NIL(head, null, rest) null
# define HEAD(head, null, rest) head
# define TAIL(head, null, rest) TOK(rest)
# define FOLDR_0(list, f, z) IF(IS_NIL list)(z, f(HEAD list, FOLDR_1(TAIL list, f, z)))
# define FOLDR_1(list, f, z) IF(IS_NIL list)(z, f(HEAD list, FOLDR_2(TAIL list, f, z)))
# define FOLDR_2(list, f, z) IF(IS_NIL list)(z, f(HEAD list, FOLDR_3(TAIL list, f, z)))
# define FOLDR_3(list, f, z) IF(IS_NIL list)(z, f(HEAD list, z))
946 :
続き :2006/04/04(火) 21:16:34
/* 型認識 */ # define TYPE_INFO(ts) FOLDR_0(TOK(ts END), ADD, (false, false, false, false, false, int)) # define ADD(type, attr) CAT_I(ADD_, type) attr # define ADD_signed(sig, un, l, ll, s, b) (true, un, l, ll, s, b) # define ADD_unsigned(sig, un, l, ll, s, b) (sig, true, l, ll, s, b) # define ADD_char(sig, un, l, ll, s, b) (sig, un, l, ll, s, char) # define ADD_short(sig, un, l, ll, s, b) (sig, un, l, ll, true, b) # define ADD_long(sig, un, l, ll, s, b) IF(l)((sig, un, l, true, s, b), (sig, un, true, ll, s, b)) # define ADD_int(sig, un, l, ll, s, b) (sig, un, l, ll, s, b) /* シンボル生成 */ # define TYPE_SYM(sig, un, l, ll, s, b) TYPE_SYM_ ## b(sig, un, l, ll, s) # define TYPE_SYM_int(sig, un, l, ll, s) PREFIX_IF(un, U, IF(ll)(LLONG, IF(l)(LONG, IF(s)(SHRT, INT)))) # define TYPE_SYM_char(sig, un, l, ll, s) IF(sig)(SCHAR, IF(un)(UCHAR, CHAR)) # define TYPE_MAX(ts) CAT(SEP(TYPE_SYM, TYPE_INFO(ts)), _MAX) TYPE_MAX(signed char) /* SCHAR_MAX */ TYPE_MAX(long long int) /* LLONG_MAX */ TYPE_MAX(signed) /* INT_MAX */
すげぇ(・д・)
よめねえ。 BOOST::PREPROCESSORを思い出した…
いかなる予備知識があったらこのコードにたどり着くのか。 実に興味深い。
もしかしてプリプロセッサのマクロってTuring完全なのか……?
>> 945 そのコードはVC6だとコンパイル不可? こんな↓WARNING&エラーが出てしまいました。 warning C4003: マクロ 'IS_NIL' に指定された実引数の数が少なすぎます。 warning C4003: マクロ 'CAT_I' に指定された実引数の数が少なすぎます。 warning C4003: マクロ 'HEAD' に指定された実引数の数が少なすぎます。 ・・・ (略) ・・・ error C2065: 'TYPE_SYM' : 定義されていない識別子です。 error C2146: 構文エラー : ';' が、識別子 'IF_' の前に必要です。 error C2065: 'IF_' : 定義されていない識別子です。 error C2062: 型 'int' は不要です。
>>952 ごめん。書き忘れてた。
>>945 はgccとBoost.waveで通ることを確認した。
試してないけど、DigitalMarsの最近のバージョンでも通るかも知れない。
それ以外のプリプロセッサだとたぶん通らない。
え、カスじゃん
趣旨を理解しろよ駄馬。
つまりカスだってことでしょう
プリプロセッサにコンパイラ依存なんかあるもんなのか・・・ マクロ展開できる深さに制限があるとかならともかく、そもそも展開方法が違うとは。 プリプロセッサなんてC言語のときから変わってないものと思ってた。
すごいっちゃすごいけど、あんまり使い道が無いなw
これでいいんじゃね? #define TYPE_MAX(type) (\ strcmp(#type,"char")==0?CHAR_MAX:\ strcmp(#type,"short")==0?SHRT_MAX:\ strcmp(#type,"int")==0?INT_MAX:\ strcmp(#type,"long long")==0?LONG_LONG_MAX:\ strcmp(#type,"unsigned char")==0?UCHAR_MAX:\ strcmp(#type,"unsigned short")==0?USHRT_MAX:\ strcmp(#type,"unsigned int")==0?UINT_MAX:\ strcmp(#type,"unsigned long long")==0?ULONG_LONG_MAX:0)
typedefしてたら?
即値じゃなきゃ駄目でしょー
gccは翻訳時に関数を実行して定数化するオプションがあると聞いたことある。 例えば a = strlen("ABC") を a = 3 にしてしまうとか。
プリプロセッサより前に実行される関数はありません。
デッドロックしてねえで前に進め。
ヒント:即値
つまり
>>962 では即値が取得できないから意味が無いってことだろ。
日本に来て日が浅いんだろう。
>>962 >gccは翻訳時に
プリプロセスの時点ではまだ即値になってないんだろ。
しかし、コンパイル時にはstrcmp(リテラル, リテラル) になるから コンパイラがstrcmpの仕様を知っていれば最適化できる、ということかな。 関数を実際に実行するというのは無理だもんね。
まあ、俺の下痢便でも飲んで落ち着け。
>>974 事前にコンパイルされている関数なら実際に実行するのは無理ではないだろうね
static/グロバーバルな変数を使わずハードも叩かない関数については
純粋関数としてマークしておいて、
コンパイル時に呼び出して即値入力をさせて結果を出すとかさ
OCXとかDelphiなんかはコンパイル時ではなく設計時にコンパイル済のモジュールを実際に動かしてるよね
>>977 gccのドキュメントは読んだのか?
ぐぐったらstrcmpの最適化については書いてあったぞ。
gccの実装の話をしていたのか?
gccの最適化の話じゃないのか? 話が噛み合ってない理由がわかった希ガス
いや、だからコンパイラが関数の仕様をしらなくても 純粋な関数なら入力に対して出力は必ず一意に定まるのだから 純粋な関数に定数の入力があれば、コンパイル時にその関数を実行させて 結果を定数化する事は可能だろうという事。 純粋な関数≒状態を保持しない で 状態を保持しないかどうかはコンパイル時に判るのだから
だからおまいら何の話してるのかそれぞれ言ってみろw
gccの関数を定数に置き換える変なオプションはトリッキーってことでFA?
>>981 外部にあるライブラリ関数だから純粋関数の判定はそう簡単ではない
やるとすればいくつかの関数を決め打ちにするしかなさそうだ
しかしライブラリ関数をinlineで実装してはいけないという規定は無いわけで……。
ハァ?誰が淫乱関数の話してんだよヴォケが。
もうそろそろスレ違いだから他でやんな。 gcc固有の動作ならそういうスレがあんだろが。
*
*
*
*
※
米
(゚∀( * )
あふ
埋めますか。
まぁネタがねえならな。乙乙。
998 :
デフォルトの名無しさん :2006/04/25(火) 21:35:51
//
1000なら、オナヌーする
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。