C/C++小心者スレッドP ..
[2ch|▼Menu]
775:デフォルトの名無しさん
10/01/15 19:05:36
まーゲームなんかだと変数名にシリアル振りたくなることはある
でも今時そこまでガチに汚く組まないと困ることはコンシューマでも珍しい

776:デフォルトの名無しさん
10/01/15 22:33:15
意味は異なるが関連のある変数?
なら構造体にするとか

777:デフォルトの名無しさん
10/01/16 17:07:00
ポインタを配列形式でアクセスするとき、添字に負の数を指定するのは文法上許されるのでしょうか。
int a[10];
int *p = a+5;

p[-4] = 0;

778:デフォルトの名無しさん
10/01/16 17:10:40
>>777
値の正負は文法上の問題ではないので、非負の値が許されるなら当然、文法上は、有効。

779:デフォルトの名無しさん
10/01/17 00:43:20
けどすごい紛らわしい書き方だな…

780:デフォルトの名無しさん
10/01/17 12:01:30
まぁ素直に*(p-4)=0と書いた方がいいわな。1[p]とかと似たような空気を感じる。

どうでもいいけど、-4[p]=0は試してないけど有効じゃなさそうだな、優先順位的に。

781:デフォルトの名無しさん
10/01/17 18:13:26
一連の流れでmalloc/freeを連想した

782:デフォルトの名無しさん
10/01/17 20:05:01
>>780
(-4)[p] なら大丈夫

783:デフォルトの名無しさん
10/01/17 20:17:49
そんな書き方、文法が許しても俺が許さん

784:デフォルトの名無しさん
10/01/17 20:38:04
コーディング規約とかで人のプログラミングスタイルを制限するのは
ナンセンスだと思っている俺ですら>>782はぶち殺したくなる


785:デフォルトの名無しさん
10/01/18 09:30:44
べつにいいやんw 一箇所だけとか、少ないときは。
きっと清涼剤のようにさわやかになれるぞ。

786:デフォルトの名無しさん
10/01/18 09:40:05
なれねーよw

787:デフォルトの名無しさん
10/01/18 21:22:34
マジックナンバーならまだ一目でわかるが

int a[10];
int *p = a+5;
int n = -4;
/* 数十行のコード */
n[p] = 0;

とかなってたら明確な悪意を感じる

788:デフォルトの名無しさん
10/01/19 20:40:13
すみません。
共通の変数50個を扱うデータクラスA(インスタンスは500個)に関連して
10種x1〜20の配列(ムラの激しい追加情報)が必要なのですが、
全部データクラスAに入れてしまうと、約190個x400インスタンス=76000個分ほどの変数は無駄になる計算で・・。
STLを使うなりクラスをバラにするなり考えているのですが
こういう場合、どうデータを管理するのが定番、妥当なのでしょうか?

789:デフォルトの名無しさん
10/01/19 21:05:01
たかが76000個くらい気にしない、というのも一つの解決方法

790:デフォルトの名無しさん
10/01/19 21:24:38
76000個のインスタンス一つは組み込み型程度なの?
とりあえず気にしないで作ってだめそうだったら工夫するとか?
76000個をヒープに取ったらまずい?


791:デフォルトの名無しさん
10/01/19 21:44:52
使うときに使う分だけ配列を確保すればいいんじゃね?

792:デフォルトの名無しさん
10/01/19 23:57:49
それは本当に配列でなければいけないの?

793:デフォルトの名無しさん
10/01/20 01:55:58
>788
>共通の変数50個
この段階でクラスの切り分け方ミスってるような気もするが。

追加情報については STL のコンテナ使うなり(コンテナの選択は追加、削除、検索の発生の仕方次第)、
適当なクラスにラップするなり、ケース次第だと思う。
追加情報に対して単なるコンテナ以上の操作が必要ならばクラスにラップするかもね。

794:デフォルトの名無しさん
10/01/22 19:56:01
>>789-793
ありがとうございます。巻き添えらしいアクセス制限で返事が遅れてすみません。
今は、言われてみれば数十KB位のようですし、そのままデータクラスAに入れて使う事にします。
問題になってきたらご助言を参考に改良したく思います。
ありがとうございました。

795:デフォルトの名無しさん
10/01/27 13:10:49
すいません。
DIRECT法(DIviding RECTngle)のプログラムを組むことになったのですが、
どうにもとっかかりが無くて困っています。
おおよその理論は分かっているのですが、形にすることが全くできません。
ググって見たりはしたものの、それらしきプログラムソースは落ちていませんでした。
助けていただくことはできますでしょうか?


796:デフォルトの名無しさん
10/01/27 13:36:39
>>795
ググると普通にあるけど…?
ソースが欲しいって訳?

797:デフォルトの名無しさん
10/01/27 18:44:46
>>796
ソースがあれば、いただけると幸いです。

798:デフォルトの名無しさん
10/01/29 17:20:14
795
どなたかお願いします。
書き忘れましたが、C++です。

本当に困ってます

799:デフォルトの名無しさん
10/01/29 17:43:15
留年したまえ

800:デフォルトの名無しさん
10/01/29 17:53:41
>落ちていませんでした

こういうこと書かれると手伝う気うせる

801:デフォルトの名無しさん
10/01/29 20:13:46
>>800
なんでだよw

802:デフォルトの名無しさん
10/01/29 20:25:14
>>801
なんでだよじゃねえだろ。失礼甚だしい

803:801
10/01/29 22:04:27
>>802
まあ・・・確かに落ちているという表現はあまり良くなかったかもしれんな。

ま、その辺は本人がきっと弁明するということで。


804:デフォルトの名無しさん
10/01/29 22:32:16
>>803
お前がその本人だろ・・・
何しれっと他人の振りしてんだよ

805:デフォルトの名無しさん
10/01/30 00:01:15
>>804
いや別人だから失敬な。


まあ何だっていいけど。
証明方法がないもんなぁ。


806:デフォルトの名無しさん
10/01/30 16:20:48
795です。
ご指摘の通り「落ちている」という表現は悪かったと反省してます。
ただ本当に困っています。どなたか助けてくれる方いましたら
本当にお願いします。

807:805
10/01/30 16:26:09
>>806
このスレには低能力者しかいないから
別のスレ(スレリンク(tech板)とか)
に行ってみたらどうでしょうか?

> 証明方法
fusianasanがあったか。
でもまあ晒したくないからやめとこう。

808:805
10/01/30 18:03:11
>>806
言い忘れたが、常識で考えてくれ。
このままだとマルチポストになるぞ。

どっちかでは別スレに行ってきますと断りをいれましょう。


809:デフォルトの名無しさん
10/01/30 18:25:36
すいませんでした。別スレ行きます

810:デフォルトの名無しさん
10/01/30 19:22:32
.                   ____
    _              | (・∀・) |
   `))             | ̄ ̄ ̄ ̄
    ´             ∧
                <⌒>
                 /⌒\
       _________]皿皿[-∧-∧、
    /三三三三三三∧_/\_|,,|「|,,,|「|ミ^!、
  __| ̄田 ̄田 / ̄ ̄Π . ∩  |'|「|'''|「|||:ll;|
 /__,|==/\=ハ, ̄ ̄|「| ̄ ̄ ̄ ̄|「| ̄ ̄|
/_| ロ ロ 「 ̄ ̄ ̄ | | 田 |「|  田 田 |「|[[[[|
|ll.|ロ ロ,/| l⌒l.l⌒l.| |    |「|        |「|ミミミミミミ

811:保守
10/02/06 11:57:12
URLリンク(exlight.net)
C++の初期化指定は複雑
C++の初期化は恐ろしく複雑になってて,

struct S {
int a;
static int b;
int c;
} s = { 1, 3 };

と書いたらs.a = 1,s.c = 3と初期化されるなんてルールも決まっている.あんまり深入りしないでおこう….


812:デフォルトの名無しさん
10/02/06 13:12:32
複雑というより落とし穴だらけ、という感じだな

813:デフォルトの名無しさん
10/02/06 14:04:51
>>811
まあねえ
静的メンバは外で定義しないといけないしね
そうしないとコンパイラから叱られる

814:デフォルトの名無しさん
10/02/06 17:21:56
だが、スタティックメンバ変数程度で*恐ろしく*複雑ってのは、さすがにどうよ?
そりゃCよりは複雑だけど、C++に限らず、いまどきの言語でクラス変数使ったら
同じような状況になるし、少なくともスタティックメンバ変数の初期化ルールは
*恐ろしく*なんて形容されるほどじゃないと思うんだが。

ついでに聞きたいんだけど、C++に限らず、みんなが「こいつは複雑だ」と思った
言語仕様ってある?
例えば多重継承とかテンプレートとかは複雑?簡単?

815:デフォルトの名無しさん
10/02/06 17:49:22
テンプレートの部分特殊化のルールは複雑だと思う

816:デフォルトの名無しさん
10/02/06 17:50:05
あとADLは時々わけがわからなくなる
STLが吐く長いエラーメッセージはさすがに慣れたけど

817:デフォルトの名無しさん
10/02/06 17:55:31
ヘッダに const 定義しても ODR にならない場合のルールは複雑だ。

818:デフォルトの名無しさん
10/02/07 11:35:00
そりゃわかにくく書こうと思えばわかりにくく書けるさ
とにかく他人にも,そして自分にもわかりやすく書くだけ
忘れた頃に見ても

819:デフォルトの名無しさん
10/02/10 02:26:30
座標入れようと思ってdouble[3]のvectorを作ったはいいが、push_backしたときにエラー出る。
仕方ないから

struct XYZ{
double array[3];
XYZ(){}
XYZ(const XYZ&xyz){memcpy(array, xyz.array, sizeof(double)*3);}
~XYZ(){}
XYZ &operator[](unsigned int n){ return array[n]; }
};

って作ったけど、もっと楽にできなかったのかなぁ?

820:819
10/02/10 02:32:51
あ、そんなの言うと、普通にvector<vector<double> >使えって言われそうだけど、
大量の要素を入れたかったんで、double配列いっこいっこに、mallocの管理領域使うのがもったいなかったんだ。
あと、vector<double>にしといて、[i][j]を[i*3+j]ってしたり、ループするときにイテレータ3個飛ばしにしてもよかったんだけど、
なんかそこらへんでコードが地味に複雑化するのが嫌だったんだ。

821:デフォルトの名無しさん
10/02/10 05:43:20
>>819 boost::array<double, 3>

822:デフォルトの名無しさん
10/02/10 07:02:33
要素が3つくらいならboost::tupleとか。
配列っぽく扱える必要があるなら使えないが。

823:デフォルトの名無しさん
10/02/10 07:26:33
boost::arrayがせいかいじゃね?

824:デフォルトの名無しさん
10/02/10 10:25:35
>>819
POD型の配列にはコピーコンストラクタがないからエラーになるんだろ

825:デフォルトの名無しさん
10/02/10 11:09:45
>>821
そんなのがあったのですね。トンクス

826:デフォルトの名無しさん
10/02/18 07:34:09
すみません。Visual C++ 2008 Express Editionで
ブレークポイント(行の左に赤丸)を付けてデバッグ開始をした時に
・ちゃんと矢印が出て止まる状況
・透明な円になり、黄色い△に!が付いて止まらない状況
の2パターンが起きるのは何故なのでしょうか?

以前はちゃんとブレークポイントを入れれば矢印で止まってくれたのですが、
今は止まってくれず、無理に手前のブレークポイントからステップインすると
ソースを表示できない とか 逆アセンブル画面へ とかと出てしまいます。
どうすればコードを辿れるようになるでしょうか・・。

827:デフォルトの名無しさん
10/02/18 10:17:30
変更したのにビルドされてない、とか別の場所のソースだったりとか

828:デフォルトの名無しさん
10/02/18 15:12:40
デバッグビルドにするとか

829:デフォルトの名無しさん
10/02/18 15:25:45
あーリリースビルドで最適化で消されてると中抜きの丸になるな

830:デフォルトの名無しさん
10/02/18 20:31:00
>>827-829
情報ありがとうございます。デバッグモードのままでこうなるのですが・・
頂いた情報から調べてみようと思います。 ありがとうございました。

831:デフォルトの名無しさん
10/02/18 20:44:20
すみません。今まで殆どの定数を、
「ヘッダーファイルに#define」で作っていたのですが、
配列の要素数宣言などに使うわけでもなく、ただ1ソース内の複数メソッドで使う数値などは
そのソースのグローバルスコープにstaticで作った方が良い気がしてきたのですが、
これはプログラミングの常識として、やらないべきなのでしょうか? やるべきなのでしょうか?

832:デフォルトの名無しさん
10/02/18 22:09:58
>>831
> そのソースのグローバルスコープにstaticで作った方が良い気がしてきたのですが、
C言語ならそのソースの頭で#defineすれば良い。
C++ならconst定数を使うべき。
いずれにせよやらないべき。

↓↓C++にて↓↓
今までは
#define max_num 100
としていたところをヘッダに
const int max_num = 100;
と書けばよい。
URLリンク(www7b.biglobe.ne.jp)


833:デフォルトの名無しさん
10/02/18 22:18:11
>>831
1ファイルだけでしか使わないなら、そのファイルの先頭で定義するのは普通。
C++ならconst使え、とは832も言っているとおりだが。

834:デフォルトの名無しさん
10/02/19 00:11:02
>>832-833
ありがとうございます。用途に応じてconstを使うよう心がけようと思います。

835:デフォルトの名無しさん
10/02/26 00:36:35
2つ質問させていただきます

(1)
char* x = "ABC";
*x = 'x';

を実行するとエラーになるのですが、なぜ2行目の代入はうまくいかないのでしょう

(2)
void test(const int n)
{
int a[n];
}

int main()
{
test(5);
}

を実行すると、

定数式が必要です。
サイズが 0 の配列を割り当てまたは宣言しようとしました。
'a' : サイズが不明です。

というエラーが出てコンパイルできません。
testの仮引数を定数にしたので配列が作れると思ったのですがなぜだめなのでしょう。


836:デフォルトの名無しさん
10/02/26 02:03:41
>>835
(1) URLリンク(www.kouno.jp)
(2) URLリンク(www.kouno.jp)

837:デフォルトの名無しさん
10/02/26 02:58:24
>>836
ありがとうございます。(1)はわかりましたが、(2)に関しては

const int n = 5;
int a[n];

はコンパイルでき、違いがよくわかりません。
関数として用いる場合(>>835の書き方)は事実上定数になっていない、ということでしょうか

838:デフォルトの名無しさん
10/02/26 03:21:53
>>837
それがコンパイルできるなら、たぶん C++ 使ってるんじゃないかと。

839:デフォルトの名無しさん
10/02/26 04:04:15
>>838
どこでCとC++の区別をつけるのかいまいちよくわかっていませんが、
C++のつもりで書いていました。

840:デフォルトの名無しさん
10/02/26 04:12:29
>>839
コンパイラが違う

841:デフォルトの名無しさん
10/02/26 04:24:55
>>839
CからC++が派生する過程で、constがついている変数は定数とみなすようにルールが変更された。
逆に言うと、constがなければ定数とはみなさない、というルールなので従うしかない。
VC系コンパイラなら、拡張子をcにすればconstがついていてもエラーになると思う。

これがgccだと>>835の(2)すら通っちゃうんだが、言語仕様上はエラーになるのが正しい、はず。

842:デフォルトの名無しさん
10/02/26 04:28:04
>>841
gcc で通っちゃうのはおそらく C99 の仕業。たぶん const なくても通る。

843:デフォルトの名無しさん
10/02/26 04:41:14
C99制定前からのGCC独自拡張です

844:デフォルトの名無しさん
10/02/27 14:16:59
質問です。
URLリンク(bal4u.dip.jp)
ここの「数字変換 10進数を2進数に変換 dec2bin」を、
10進数から3進数へ変換するようにしたいのですが、うまくいきません。
どのようにしたらよいでしょうか。

845:デフォルトの名無しさん
10/02/27 14:43:18
>>844
どうしたらうまくいかなかったを書かないとなんともいえない。


846:デフォルトの名無しさん
10/02/27 15:32:41
親クラス -(継承)-> 子クラス -(継承)-> 孫クラス

というクラスで、孫クラスを親クラスに見立てて扱いたい(多態)と思い、

(親クラス型)孫クラス

というふうにアップキャストしようとしたら、コンパイラに怒られました。

こういうの、って設計がマズいということでしょうか・・・

847:844
10/02/27 15:33:03
do
{
r = 0;
non_zero = 0;
for(i = dec_len - 1; i >= 0; i--)
{
d = tmp[ i ];
tmp[ i ] = d / 3;
if(r > 0){tmp[ i ] += 3;}
if(tmp[ i ] > 0){non_zero = 1;}
switch(d)
{
case '0': r=0;break;
case '1': r=1;break;
case '2': r=2;break;
case '3': r=0;break;
case '4': r=1;break;
case '5': r=2;break;
case '6': r=0;break;
case '7': r=1;break;
case '8': r=2;break;
case '9': r=0;break;
}
//r = d & 1;
}
bin[ bin_len++ ] = r;

}while(non_zero);

主要部分を改造した物を上げて見ます。
ごらんの通り、答えが合いません。
全体的に訳が分かりません。(元のソースは理解できましたが……)

848:デフォルトの名無しさん
10/02/27 18:24:32
>>846
その変換は暗黙の変換で通るはず。
これ以上はエラーメッセージやソースを晒してもらわないとわかんない。

849:デフォルトの名無しさん
10/02/27 18:32:43
>>844,847
元のソースから変数名が適当で読みにくいソースだね。わけがわからないのはそのせいじゃない?

素直に一旦ふつうの整数値として取り出して3進の文字列に書き出すようにしたほうが
簡単だと思うよ。整数値に変換する部分は strtol() 使えば一発だし。

850:844
10/02/27 19:44:37
>>849
多倍長演算ってことになっているので、いったん数値に戻すっていうのも難しそう。
一応 50桁の10進数を3進数に変換したいと考えています。
他に簡単に10進 3進の相互変換が出来そうな仕組みはありませんかね。

とりあえず一桁の時の答えだけは合うようになった(笑)


851:846
10/02/28 15:24:38
>>848
すみません、何か勘違いしていたようです。
問題なく動きました。
失礼しました。

852:デフォルトの名無しさん
10/02/28 23:07:29
>>850
849 同様に俺も数値にした方がミスしにくいし応用も効くしいいと思うけどな
桁数多くてもgmp みたいなものもあるし,必要なら自分で class 作っても良いし

まぁ目的に依るけどね
>>844 のコードを変更することだけが目的ならしょうがないけどね


853:デフォルトの名無しさん
10/03/07 20:07:36
初歩的な質問すみません、BYTE配列からDWORD型変数に数値をコピーした時、
1バイト分しかコピーできないのですが、(256以上が0…1…2… となってしまいます。)
どうすれば8バイト分コピーできるのでしょうか。

854:デフォルトの名無しさん
10/03/07 20:49:47
> BYTE配列からDWORD型変数
C/C++にそんな型は存在しません。

MFCの用語はスレチな気がする。
スレリンク(tech板)
こことかか?

855:デフォルトの名無しさん
10/03/07 20:59:30
>854
MFC っていうか Win32 だと思われ。
書いてる事そのものは memcpy とか CopyMemory だけどそれが本当に自分のやりたい事かどうか
確認した方がいいかもしれない。

856:デフォルトの名無しさん
10/03/07 21:01:36
>>854
> C/C++にそんな型は存在しません。

小心者スレッドなんだからまあ良いではないか。

>>853
どんなコードでコピーしたの?
そもそもBYTE型に256以上の値は入らないし、DWORDだったら4バイトだよね。


857:854
10/03/07 21:21:41
>>856
> 小心者スレッドなんだからまあ良いではないか。
一応 小心者 向けに多少はしたつもりだったんだが、
俺の言い方はやっぱまだ厳しかったか。
スマン


858:デフォルトの名無しさん
10/03/07 21:40:13
コード見たほうが早いなたぶん

859:853
10/03/08 00:08:15
>>854-858
ありがとうございます、memcpy使えば良かったですね、
他の事に気がいっててそんな事にも気付かなかった、 orz
あとDWORDは4バイトだったんですね、ご指摘ありがとうございました。

860:デフォルトの名無しさん
10/03/08 10:55:08
配列ならポインタを強引にキャストするだけでもよくね
メモリ上の配置の把握が必要だけど、memcpyするにしてもそれは必要だし

861:デフォルトの名無しさん
10/03/08 12:43:22
>>860
エイリアシングルールというものがあってだな。
URLリンク(www.radiumsoftware.com)

862:デフォルトの名無しさん
10/03/09 03:46:00
8bit変数配列→32bit変数、ってだけならunion作れ
8bit変数配列→32bit変数配列、とかならどうしたもんだか

863:デフォルトの名無しさん
10/03/12 22:33:09
unionつかったらエンディアンの問題はどうするの?

864:デフォルトの名無しさん
10/03/12 23:04:11
2倍あるいは1/2倍していたところをビットシフトに書き換えたら、若干遅くなりました。
同じかそれ以上の速さになることはあると思っていましたが、遅くなるとはどういうことなんでしょうか??
CPUには乗算や除算のほうが高速に行える回路が付いてるんでしょうか??

865:デフォルトの名無しさん
10/03/12 23:45:00
>>864
推測ではどういう風にでも考えられるので
コンパイラにアセンブリを吐き出させてみればどうでしょう

866:864
10/03/13 01:38:25
>>865
ありがとうございます。
アセンブラは読めませんが、がんばって解読してみます。

867:デフォルトの名無しさん
10/03/13 10:20:26
>>863
気になるなら#ifdefするなり効率落として変換関数書くなりすればいいんじゃね
綺麗で効率いい方法は知らん

868:デフォルトの名無しさん
10/03/13 10:40:47
絶対にWindowsでしか使わないのにクロスプラットフォームで書きたくなる病とかあるよな

869:デフォルトの名無しさん
10/03/13 12:11:15
>>868
できる限り標準に準拠するのは正しい態度だと俺は思うよ

* ずっとWindowsだけの仕事をするとは限らん
* 元々Windowsだけのつもりでもコードの一部流用とかすることがありうる


870:デフォルトの名無しさん
10/03/13 13:45:37
8bit配列→32bitなんていう処理についての話からの流れだからなぁ
汚くする理由の無い部分は綺麗に書くのが当然だが、エンディアン絡みの処理を
すっきり綺麗に効率良く、って訳には行かんだろ現状

871:デフォルトの名無しさん
10/03/13 14:15:49
>>869
* 言語標準に準拠しつつクロスプラットフォームではないコードは極めて一般的
* OS標準に準拠しつつクロスプラットフォームでないコードは言うまでもなく一般的
* そもそも「絶対に」という前提の話

まず、クロスプラットフォームと規格準拠は全くの別物。前者の需要は極めて稀。
Windowsアプリを書く時にクロスプラットフォームにしようとするのは、かなり病的
にならないと困難だと思うぞ。犠牲も大きいし。

872:デフォルトの名無しさん
10/03/13 15:25:22
Qtとかの外部ライブラリを使えば
クロスプラットフォームでも楽に書けるぞ。


873:デフォルトの名無しさん
10/03/13 21:57:02
>>871
プラットフォーム依存性が必要無いところは敢えて依存性持たせない方が
良いと俺は思うけどな
必要もなくプラットフォーム依存してるコードもよくあるが
元々絶対に流用しないつもりでも一部切り貼りって結構あると思うぞ

874:デフォルトの名無しさん
10/03/13 22:02:26
forループのインデクスすらDWORD使うサンプルとかあるからな

875:デフォルトの名無しさん
10/03/14 07:46:33
程度問題だな。病気レベルの無駄なことはやらない方がいい。無理せずに依存無く
書けるなら当然その方がいい。
Qtは微妙だろ。必要も無しにあれを選ぶ理由は無いと思う。

876:872
10/03/14 10:36:59
別にQtじゃなくても、とにかくクロスプラットフォームな外部ライブラリなら
俺の言いたいことは伝わると思うんで、適当に読み替えてください。

877:デフォルトの名無しさん
10/03/14 15:01:47
クロスプラットフォームなフレームワークに乗っかれば
クロスプラットフォームでも楽に書けるぞ。

・・・当たり前だろjk

878:デフォルトの名無しさん
10/03/15 00:23:17
本気で細かいことをしようとするととても楽に書けるなんてもんじゃないから、
普通は細かいことをバッサリ諦めるしか無いのがクロスプラットフォーム

879:デフォルトの名無しさん
10/03/15 00:27:38
まぁGUIに関しては特にそうだよね

880:デフォルトの名無しさん
10/03/15 08:24:51
独自機能は全部諦めることになるしなぁ

881:デフォルトの名無しさん
10/03/15 21:37:14
>>878
細かいこと気にしない方が逆にいいものできたりして…
稀かもしれんが

882:デフォルトの名無しさん
10/03/15 22:23:42
>>881
「逆にいい」は稀かと
あっても無くても関係ない、ならまだそれなりにある話だが

CUIなら割と素直にクロスプラットフォームになりやすいけどな
それでも、元の流れの内容をエンディアン違いにまで対応させようとしたら
あまり綺麗には済まないが

883:デフォルトの名無しさん
10/03/16 21:46:48
CUIでも、実用品でクロスプラットフォームなコードになると大抵はマクロで個別に
ソース分岐させてるけどな。C/C++標準だけで書ける実用品なんて小物だけ。
LinuxとBSD系ですら、パフォーマンスを実用レベルにする為には移植作業が必要に
なったりする訳で。Windowsならなおのこと。

884:デフォルトの名無しさん
10/03/16 21:56:00
標準の範囲ではWindowsでUnicodeファイル名を扱えないし
ディレクトリすら作れないし
バイナリファイルを標準入出力で読み書きできないし
大きなファイルのシークもできない

885:デフォルトの名無しさん
10/03/16 21:57:51
だからクロスプラットフォームなフレームワークに乗っかろうぜ
と言ってるじゃないか。
だれもC/C++標準だけで満足はしないさ。


886:デフォルトの名無しさん
10/03/16 22:03:09
オープンソースだと、単にWindowsのUnicodeファイル名などは
切り捨てているものも多いな

887:デフォルトの名無しさん
10/03/16 22:18:27
そしてパスに空白を含むと落ちるクソアプリができあがると

888:デフォルトの名無しさん
10/03/16 22:24:03
>>887
> そしてパスに空白を含むと落ちるクソアプリができあがると
たまにそういうクソアプリが見つかるけど、
それが原因だったんかい!

889:デフォルトの名無しさん
10/03/17 01:19:44
クロスプラットフォーム向けのフレームワーク使ったところで、問題の本質の
ほとんどは解決しないよな

890:デフォルトの名無しさん
10/03/17 18:28:38
プラットフォーム依存性があるにしろオープンソースでクロスプラットフォー
ムというと firefox, thunderbird, gimp, cygwin とか思いつくけど
これらってクソアプリやへぼアプリの分類なの?

891:デフォルトの名無しさん
10/03/17 18:58:00
cygwinは最近出た1.7まではUnicodeファイル名に対応していなかった
実のところ、Windows専用でも、Unicodeファイル名に対応していないプログラムは
ものすごく多い、特にコンソールアプリケーションではそれが普通

892:デフォルトの名無しさん
10/03/17 19:20:32
>>890
必死に移植作業してマクロで分岐させるんならいくらでもクロスプラットフォームに
なるのは当然だろw

893:デフォルトの名無しさん
10/03/17 22:53:58
>>890
firefox, thunderbird, gimp, cygwin が
クソアプリやへぼアプリだったら
そうじゃないアプリって世の中にほとんどないんじゃないか?


894:デフォルトの名無しさん
10/03/17 23:49:10
クロスプラットフォームなコードでもクソじゃないのはあると言いたいんだろ
だが、あの辺のは「現実に十二分な需要がある」から、仕方なく「多大な手間を掛けて
複雑なコードを書いて」実現してるから、牧歌的な話からは程遠い

895:デフォルトの名無しさん
10/03/18 00:16:50
>>894
> クロスプラットフォームなコードでもクソじゃないのはあると言いたいんだろ

クロスプラットフォームのアプリのほとんどが
クソアプリだってことが言いたいのかい?

896:デフォルトの名無しさん
10/03/18 00:19:05
クソアプリの定義にもよるんじゃないの
例えばlameは最優秀のMP3エンコーダーだが、Unicodeファイル名には対応していない

897:デフォルトの名無しさん
10/03/18 00:31:07
英語限定ならば問題は大分少なくなりそうだな…

898:デフォルトの名無しさん
10/03/18 00:32:40
そうだな
GUIの場合、IMEという難関もあるし

899:デフォルトの名無しさん
10/03/18 11:56:10
>>895
どう見ても真逆の意味にしか読めないが

900:デフォルトの名無しさん
10/03/18 12:05:23
コードは肥大するけどお勉強の為に非依存で書いてみました、でも誰も使いません
けどね、ってのが無駄
自然に非依存なコードになるならそれでいいんだよ(エンディアンなんかは面倒な
ことをしなきゃ非依存にはならんけど)
実需があるなら無理もしなきゃならないし、変態コードが肥大しても許される

901:デフォルトの名無しさん
10/03/18 12:08:51
実装の手間自体もでかいが、テストの手間のほうがより悲惨だな

クロスプラットフォームを本気で考えるのは、プロジェクトが大きくなってからで
いいと思う

902:デフォルトの名無しさん
10/03/18 14:36:18
クロスプラットフォームにするほど
他人が使ってくれるかどうかっていうところがなw

903:デフォルトの名無しさん
10/03/18 18:14:36
>>900
> 自然に非依存なコードになるならそれでいいんだよ(エンディアンなんかは面倒な
> ことをしなきゃ非依存にはならんけど)

素朴な質問だが通常のコーディングでなぜエンディアンを
生で扱わなければいけないの?

904:デフォルトの名無しさん
10/03/18 18:20:57
>>903
誰かがエンディアンを持ち出したからだろ

905:デフォルトの名無しさん
10/03/18 18:21:42
>900ではないが
少なくとも画像や音声など、バイナリデータを弄る場合には必ずエンディアンの問題は
出てくるでしょ

ネットワークプログラミングにおけるntohl()のように、ホストエンディアンを
意識せずに「ホストエンディアンと対象エンディアン(bigないしlittle)を
変換する関数」を複数用意することで、問題を解決できることが多いと思うけど

906:デフォルトの名無しさん
10/03/18 18:35:28
>>905
画像,音声,ネットワークだと生で扱わなくてもライブラリがあるんでは
自分で用意する必要は必ずしも無いはず

907:デフォルトの名無しさん
10/03/18 18:47:09
そもそも>>900を読んで「通常のコーディングでもエンディアンを生で扱わなければ
いけない」とは読み取れないんだが

908:デフォルトの名無しさん
10/03/18 20:41:29
>>906
ま、ライブラリにおんぶにだっこでいい場合はそうだね

ただ、例えばntohl()のようなものはホストエンディアンによってコードを
分ける必要はなくしてくれるが、「ここはネットワークエンディアンに変換する
必要があるのでntohl()を呼ぶ」ような仕事は残るわけだから、
エンディアンを意識しなくてよい、というわけではないよね


909:デフォルトの名無しさん
10/03/18 22:06:47
>>908
それはどういうライブラリ使うかじゃないか?

たとえば画像の時は「必ずエンディアンの問題は出てくる」というが,
magick++ みたいなもの使えば「エンディアンを意識しなくてよい」
という状況だと思うけど違う?

910:デフォルトの名無しさん
10/03/18 22:30:11
>>909
正直議論の意味というか、何にこだわってるのか、何を知りたいのか
全く理解できんのだけど……
magick++を使ったことは無いのでわからんが、まあ、そう言ってしまえば
何だってそうだといえるだろうさ

画像処理で言うと、ファイルフォーマット内のバイトオーダーは
ライブラリによって隠蔽されるケースは多いと思う
が、ライブラリにロードしてもらった32bitラスタ画像のピクセルフォーマットが
ARGBかBGRAか、といったことは、ピクセルを弄る場合には結局必要になるわけだ

911:デフォルトの名無しさん
10/03/18 22:54:34
picture[y][x].a = 〜
みたいに使えるんでないの?
ロードの処理が重くなりそうだが。

912:デフォルトの名無しさん
10/03/18 23:01:06
>>911
一瞬意味が分からなかった、その.aはARGBのAか
まあ、そういう実装は可能だろうね
Cだと
PutPixel(point, a, r, g, b)
のような関数ないしマクロを使うんだろう


913:デフォルトの名無しさん
10/03/18 23:13:43
>>910
画像処理と言ってもライブラリを使える場合もあるから
「必ずエンディアンの問題は出てくる」ということも無いということだよ

magick++ とかを使ってできることをわざわざ車輪を再発明する事もない場合も多いし
具体的にピクセルをどう弄りたいわけ?


914:デフォルトの名無しさん
10/03/19 01:45:40
>>913
ああ、要するに「必ず」は言いすぎだろ、という突っ込みか
確かに言い過ぎたね

915:デフォルトの名無しさん
10/03/19 12:22:01
Windowsでカレントディレクトリを取得する方法を教えてください

916:デフォルトの名無しさん
10/03/19 12:36:42
GetCurrentDirectory()

917:デフォルトの名無しさん
10/03/27 23:45:49
失礼します。
C++を勉強中の初心者です。

ポインタを関数の戻り値する場合は関数内の宣言にstaticをつけなければならないという記述をよく目にするのですが、
以下のようにstaticをつけずにHoge hを宣言しても問題なくプログラムが動き、5が出力されます。どういうことなのでしょうか。

typedef struct{
int k;
} Hoge;

Hoge* func(int a)
{
Hoge h;
h.k = a;
return &h;
}

int main()
{
Hoge* h = func(5);
cout << h->k;
}

918:デフォルトの名無しさん
10/03/27 23:59:25
>>917
Hoge h がスタック上に作られている場合、関数から帰ってきた
直後は問題ない可能性が高いが、もう1回func()を呼んだり
別の関数を呼んだりすると、おかしくなる可能性がある。

919:デフォルトの名無しさん
10/03/28 00:02:59
>>917
動くのはたまたまです
試しに、func(5) のあとに別の関数を呼んでみてください
別の結果になると思います

920:デフォルトの名無しさん
10/03/28 00:16:44
なるほど
たしかにおっしゃるとおりの事態が起きました。
ありがとうございます。

あと実はこのことに直接関わるかはわからないのですが、
別のプログラムにおいて、同じように構造体のポインタを戻り値とする関数をつくって内部の宣言をstatic有りと無しどちらも試したところ、
staticをつけた方はmainを抜けるところで停止してしまいます。
関係があるのかどうかよくわかりませんが、もし心当たりがありましたらお教えいただけると幸いです。

921:デフォルトの名無しさん
10/03/28 00:23:11
>>920
ソースをcodepadに貼れ
言ってる事がよくわからない

922:デフォルトの名無しさん
10/03/28 00:25:57
>>920
そんなことで悩むぐらいならポインタでなく実体を返せばいいと思う

Hoge func(int a)
{
Hoge h;
h.k = a;
return h;
}


923:デフォルトの名無しさん
10/03/28 01:30:09
>>922
構造体の配列を返したかったので・・・

すみませんどうやら別のところで引っかかっていたようで、今解決しました。
どうもお騒がせしましてすみません。

924:デフォルトの名無しさん
10/03/28 03:13:39
つーか根本的に関数側で確保した構造体のポインタを返すのがキモイ
呼び出し側で(空でいいから)構造体を用意して、そのポインタを関数に渡して、
関数側はその渡されたポインタで構造体の中身を加工する、っつーのが普通だし、
そういう設計ならポインタを返す必要も無いしstaticも要らないし、static無しで
ポインタ返しても別に問題無い
何でそうなるかが分からんようだと辛い

925:デフォルトの名無しさん
10/03/28 09:22:50
>>924
関数側で確保した構造体のポインタじゃなくて構造体を返すのもダメ?

926:デフォルトの名無しさん
10/03/28 10:41:34
>>924-925
(コピーのオーバーヘッドはおいといて)1個の構造体や、固定長の構造体配列ならそれでもいいんじゃないの?
任意個数の配列をポインタではなく値で返す方法ってのを俺は知らないのだけど、どんなのがある?

>>920
staticつけないのは論外として、つけてもポインタの指し示す先が共有されていることは理解してる?
int *func(int n){
static int a;
a=n;
return &a;
}
int main(void){
int a,b;
a=func(1);
b=func(2);
printf("a = %d, b = %d\n", a, b); /* a = 2, b = 2 */
return 0;
}

927:926
10/03/28 10:42:50
ごめ、すっとぼけてた。
int main(void){
int *a,*b;
a=func(1);
b=func(2);
printf("*a = %d, *b = %d\n", *a, *b); /* *a = 2, *b = 2 */
return 0;
}

928:925
10/03/28 13:39:27
デザインの問題だけどたとえば何かデータをファイルから読むとか
与えたデータから新しいデータを作るというときに

const vector<double> parseData(double x,vector<double> v,...){
vector<double> v1;
…vector 領域確保して,データを料理してv1に入れる…
return v1;
}
int main(){
...
vector<double> vData(paseData(x,v,...));
}

みたいなのはなぜいかんのかなと思って

void parseData(vector<double>&v1,double x,vector<double> v,...){
…vector 領域確保して,データを料理してv1に入れる…
}
int main(){

vector<double> vData;
paseData(vData,x,v,...);
}

みたいに必ず書かなきゃいかんのかな?(確かに昔Fortranとかはいつもこういう
スタイルだったなぁ)

個人的には前者の方が直感的だけど
簡単のため vector の例にしたけどもちろん自分で定義したデータ class でも同じこと




929:デフォルトの名無しさん
10/03/28 13:40:41
コピーが発生したら嫌じゃん

930:デフォルトの名無しさん
10/03/28 15:38:13
コピーのコストが問題にならない状況でなら、その手も使った。

931:デフォルトの名無しさん
10/03/28 16:47:51
関数内でnewしてshared_ptrで返せばいいよ

932:デフォルトの名無しさん
10/03/28 17:06:34
#include <vector>
#include <memory>
#include <iostream>

using namespace std;
using namespace std::tr1;

shared_ptr<vector<double> > parseData(double x){
    shared_ptr<vector<double> > v1(new vector<double>);
    v1->push_back(x);
    return v1;
}
int main(){
    shared_ptr<vector<double> > vData(parseData(1.5));
    cout << vData->at(0) << endl;
}

933:デフォルトの名無しさん
10/03/28 20:14:03
何でstatic付けると助かるのかを理解しない限り、いくらでも似たような問題で
引っ掛かると思われ

934:デフォルトの名無しさん
10/03/28 20:24:01
#include <iostream>
#include <vector>
using namespace std;

int sum(vector<int> vec){
int ammount = 0;
for(vector<int>::iterator it = vec.begin();it != vec.end(); ++it){ ammount += *it; }
return ammount; } // 2ch行数制限回避
int main()
{
vector<int> v;
v.push_back(1);v.push_back(2);v.push_back(3);
cout << sum << endl; // 表示結果: 6
}
はいいんだけど、sumを
template <class T, T zero> T sum(vector<T> vec)
{
T ammount = zero;
for(vector<T>::iterator it = vec.begin();it != vec.end(); ++it){
ammount += *it;
}
return ammount;
}
にして、main中のcoutの行をcout << sum<int, 0>(v) << endl;にすると
a.cpp:8: error: dependent-name ‘std::vector::iterator’ is parsed as a non-type, but instantiation yields a type
a.cpp:8: note: say ‘typename std::vector::iterator’ if a type is meant
のようになっちゃう。vector<T>::iterator itをT vector::iterator itに変えても
a.cpp:9: error: ‘template<class _Tp, class _Alloc> class std::vector’ used without template parameters
a.cpp:9: error: expected initializer before ‘it’
になっちゃう。
どう対処すればいいんでしょう?

935:デフォルトの名無しさん
10/03/28 20:29:52
>>934 URLリンク(ja.lmgtfy.com)

936:デフォルトの名無しさん
10/03/28 20:57:05
typename vector<T>::iteratorか。

937:デフォルトの名無しさん
10/03/29 20:14:09
test

938:デフォルトの名無しさん
10/03/29 20:59:59
個人的にはそろそろ>>928前者のような直接値を返すのも
VC10とかg++ 4.3とかめちゃくちゃ新しいコンパイラならはありだと思うようになってきた。
C++0xのおかげでコピー発生しなくなったから。

939:デフォルトの名無しさん
10/03/29 22:17:32
それはちゃんと右辺値参照をアレするクラスを書いた時限定じゃないのか
全てライブラリのコンテナに限定するなら構わんだろうけど

940:デフォルトの名無しさん
10/04/07 05:36:10
error: pointer to incomplete class type is not allowedってどういうことですか?

941:デフォルトの名無しさん
10/04/07 05:40:42
>>940 そのまんまだろう。

942:デフォルトの名無しさん
10/04/07 13:16:50
>>940
不透明ポインタあたりでぐぐれ


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

4744日前に更新/246 KB
担当:undef