X



【初心者歓迎】C/C++室 Ver.102【環境依存OK】
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
垢版 |
2017/11/04(土) 16:33:35.07ID:NYxCuvMY
エスケープシーケンスやWin32APIなどの環境依存なものもOK
そのような質問は必ず環境を書きましょう
半角空白やタブでのインデントはスレに貼ると無くなります

コードを貼れる所
http://codepad.org/
https://ideone.com/

前スレ
【初心者歓迎】C/C++室 Ver.101【環境依存OK】
https://mevius.5ch.net/test/read.cgi/tech/1500329247/
0761デフォルトの名無しさん
垢版 |
2018/05/11(金) 13:11:04.97ID:Mluu9Rs0
アセンブラの前に

まずは変数がどこにどのように確保されるかとか
どのように初期化されるかとか
そっちの方が先だろ

スタティック、スタック、ヒープ
をまず理解する
C++であればvirtual関数が呼ばれる仕組みとかも
知ってた方が良い
例外の仕組みは機種依存が大きいのでもうちょっと先で
0763デフォルトの名無しさん
垢版 |
2018/05/11(金) 15:32:04.47ID:L7FGnh/N
>>761
そう。
でもスタックを理解するにはメモリという概念モデルの理解が必要
だけど皆が勧めてるようなx86の解説書はやめたほうが良いと思う

セグメントレジスタとか原理を学ぶには邪魔なノイズが多過ぎる
0765デフォルトの名無しさん
垢版 |
2018/05/11(金) 17:23:03.14ID:fUD4+ayW
実用レベルのCで関数ローカル変数がどう実現されてるか、となると
ベースポインタというほぼ専用のレジスタが出てくるからなぁ。

そういえば昔、Cが全然分からない頃にMASMの本を読んだら、
Z80や6502のアセンブラではついぞ出てこないディレクティブが色々あって
まったく意味が分からなかったのを思い出した。
高級言語のコンパイラを作ったり、ライブラリとして呼べるマシン語の
サブルーチンを作るための機能なんだと後になって腑に落ちたけど。
0766はちみつ餃子 ◆8X2XSCHEME
垢版 |
2018/05/11(金) 17:39:10.37ID:e+Ei11A7
C の言語としての理屈が現代のコンピュータの仕組みと乖離しててもはや低級言語とは言えないということを
「C は PDP-11 エミュレータ」なんて揶揄してるのをどこかで見たことがあるな。
0769 ◆QZaw55cn4c
垢版 |
2018/05/11(金) 20:48:44.74ID:/s88DeTW
マシン語をやるのなら、実際に石を触れる感じのする環境がいいなあ、あくまで「感じ」だけれども
仮想マシンの中間コードを触るのは疑問
0771はちみつ餃子 ◆8X2XSCHEME
垢版 |
2018/05/11(金) 20:54:19.03ID:e+Ei11A7
AKI-80 の時代の人なのでラズパイで電子工作とかやってるのを見ると隔世の感がある。
0772デフォルトの名無しさん
垢版 |
2018/05/11(金) 20:56:49.04ID:2EGPeEG9
Donald Knuth の MMIX っていう言語は勉強するとためになりますか?
0773デフォルトの名無しさん
垢版 |
2018/05/12(土) 01:53:53.98ID:Cq1QtQw6
>>761
理解すると言っても何を勉強して理解するのか?
という話だと思ったんだけど。
アセンブリやCPU関連の本以外で具体的に分かるものがあるというのがよく分からないな。
0774デフォルトの名無しさん
垢版 |
2018/05/12(土) 04:35:38.94ID:F7LxnV/h
wikipedia の「コールスタック」の項に意外にしっかりした説明あるな
コールスタックって何?スタックフレームってなに?
って人は読んでおくといいと思う。
0775デフォルトの名無しさん
垢版 |
2018/05/12(土) 14:17:18.55ID:CbmhA0Cx
メモリとかスタックとかヒープとかって、C/C++ 言語仕様とは直接の関係がないけど、使う上では結構重要な情報だよねー。
Cを学習する上で避けられない割に、C視点側からの詳しい学習書って無いよなー。

環境依存部分だから、言語学習書に適さないってのもわかるんだが…何とかできないものかと常々思ってる。
(思ってる「だけ」で実行には移さないのだけれどもw
0776デフォルトの名無しさん
垢版 |
2018/05/12(土) 14:20:15.63ID:CbmhA0Cx
>>772
ならないと思う。
クヌース先生の本を読む上での決まり事を、先生が定義しただけに過ぎない、と理解してる。
0778デフォルトの名無しさん
垢版 |
2018/05/23(水) 19:24:44.84ID:Au5e7VGg
僕の知り合いの知り合いができたパソコン一台でお金持ちになれるやり方
役に立つかもしれません
グーグルで検索するといいかも『ネットで稼ぐ方法 モニアレフヌノ』

AA6VB
0780 ◆QZaw55cn4c
垢版 |
2018/05/24(木) 20:42:22.15ID:dCOL2CYR
>>775
たしかに、そこをつく本を書けば売れるかもしれない
そんな本に書くべきことは、他に何があるだろうか?
・qsort() の説明
・アセンブリ言語とのリンク
・PEフォーマット
…etc
0781はちみつ餃子 ◆8X2XSCHEME
垢版 |
2018/05/24(木) 21:49:22.52ID:jqqWnK8Z
>>775,780
江添氏が C++ の入門書で、言語以外の周辺事情もある程度カバーしたものを書こうとしてるみたいだぞ。
今は二の補数を説明すべきかどうかとか TWITTER でグダグダ言ってるから、
当たり前みたいで、しかし説明を省略されがちなことも含まれると思う。
0783デフォルトの名無しさん
垢版 |
2018/05/24(木) 23:04:39.55ID:agu/wXZc
浮動小数点の誤差がらみとか、バッファオーバーフローでなんで脆弱になるのかとか、キリがなくなるぞ
0784デフォルトの名無しさん
垢版 |
2018/05/25(金) 06:31:49.05ID:ZdzP9wu5
コンパイルとリンクとロードの話とか。

ソースファイルからオブジェクトファイルに変換したときに
どんな情報が残ってどんな情報が消えるか。
オブジェクトファイル群をリンクした段階でまだ確定せずに
実行時のロードで配置されるアドレスのこと、あたり。
0785デフォルトの名無しさん
垢版 |
2018/05/31(木) 19:40:53.15ID:xDJZQ821
ちょっとCと関係ないですが、コンピュータサイエンティストの人がよくMacを使っているのはなぜですか?
0787 ◆QZaw55cn4c
垢版 |
2018/05/31(木) 20:29:52.32ID:4k9lsrlf
>>781
二の補数はあたりまえに書いてもいいとおもうけれども、二の補数以外のものがあることを陽に記述する必要はないんじゃないかな…
0790デフォルトの名無しさん
垢版 |
2018/05/31(木) 22:37:50.13ID:xDJZQ821
>>788-789

ありがとうございます。

>>789

使い勝手がいいとかそういうことはないですか?
0792デフォルトの名無しさん
垢版 |
2018/06/02(土) 18:09:00.04ID:YEAzW6Zk
ヘッダーファイルについて質問なのです。
ヘッダーファイル内で、 ostream というのを使っているのですが、
#include <iostream>をヘッダーファイル内に記述していません。
エラーが出るだろうと思いつつ、ビルドしてみたらエラーが出ませんでした。

これはどういうからくりでしょうか?
0793デフォルトの名無しさん
垢版 |
2018/06/02(土) 18:23:14.65ID:tlq/OxaF
ヘッダファイルの中じゃなくostreamを使っている翻訳単位(cppファイル)の中で最低1回include iostreamされてればOK
0794はちみつ餃子 ◆8X2XSCHEME
垢版 |
2018/06/02(土) 18:25:58.96ID:LSJtd55X
>>792
他のヘッダファイルで include してて間接的に読み込んでいることになってるってのが、一番ありそうかなぁ。
0795デフォルトの名無しさん
垢版 |
2018/06/02(土) 18:30:00.66ID:YEAzW6Zk
>>793

ありがとうございました。

↓のファイルをビルドするとエラーが出るのですが、何が原因かよく分かりません。
フレンド関数関連だと思います。フレンド関数については全く知らないので、真似して
作っただけです。

Vec.h
http://codepad.org/3ROYH1yq

Vec.cpp
http://codepad.org/f3eSheBS
0796デフォルトの名無しさん
垢版 |
2018/06/02(土) 18:30:45.89ID:YEAzW6Zk
>>794

ありがとうございました。

もしかしてヘッダーファイルのみをビルドしてもオブジェクトファイルはできないんですか?
0797デフォルトの名無しさん
垢版 |
2018/06/02(土) 18:34:39.57ID:YEAzW6Zk
>>795

ある本に書いてあるコードでは、 Vec.h と Vec.cpp のようには分かれていないため、
自分で分けたのですが、エラーになってしまいました。
0798デフォルトの名無しさん
垢版 |
2018/06/02(土) 18:46:23.02ID:RQ4rJlvL
定義があればヘッダだけでもオブジェクトファイルに実装はできますよ。
0800はちみつ餃子 ◆8X2XSCHEME
垢版 |
2018/06/02(土) 18:55:56.26ID:LSJtd55X
>>799
テンプレートのエラーはテンプレートが実体化するときに出ると思うよ。
だから、テンプレートを使ってないなら、エラーがあってもコンパイル自体は出来たりする。
0801デフォルトの名無しさん
垢版 |
2018/06/02(土) 19:00:50.14ID:YEAzW6Zk
>>800
ありがとうございました。

あともう一つ質問なのですが、ロベールの本に、

「関数を実体化するには呼び出したところからその実装が見える必要があります。」

「つまり、関数テンプレートは宣言と実装をヘッダファイルとソースファイルに分離して
書くことはできず、すべてヘッダファイルで実装する必要があるのです。」

と書いてあります。

クラステンプレートについては同様の記述がないのですが、

クラステンプレートについても宣言と実装をヘッダファイルとソースファイルに分離して
書くことはできず、すべてヘッダファイルで実装する必要がありますか?
0803はちみつ餃子 ◆8X2XSCHEME
垢版 |
2018/06/02(土) 19:06:46.84ID:LSJtd55X
>>801
Yes。 テンプレートはヘッダファイルに書く必要がある。
同じ実体 (テンプレート引数も同じなテンプレート) はリンク時に統合されるので、
最終的な実行ファイルに複数の実体があったりはしない。
0806デフォルトの名無しさん
垢版 |
2018/06/03(日) 17:10:25.43ID:XweloLai
ヘッダファイルについて質問です。

assert() が使いたいため、「List2.h」内に、以下のように書いたとします。

#pragma once
#include "List.h"
#include <cassert>

実は、「List.h」内にも#include <cassert>が書いてあります。

ヘッダファイルにはすべて#pragma onceを書いているので多重インクルードについて
問題はないと思います。

そこで質問なのですが、「List2.h」内で assert() を使っているため、自分としては、
必要ありませんが、「List2.h」内にも#include <cassert>を書いた方が分かりやす
いのではないかと思いました。

既にインクルードされていてもあえて、#include <> を書くという人はいるのでしょうか?

それとも、既にインクルードされていることに気付いている場合には、できるだけ
#include <> は書かないほうがいいのでしょうか?
0807 ◆QZaw55cn4c
垢版 |
2018/06/03(日) 17:20:14.25ID:5RsKIUxf
>>806
すでにインクルードされているかどうかは書いているときにはわからない、から書いとく

ただヘッダは分割コンパイルにおいて共用するデータだけを書いておくものだから
ヘッダ List.h に #include <cassert> が含まれているのは、一見、疑問だと思った

しかしテンプレート関数に assert() が入る場合があるのだから、こういったこともあり得るのかもしれないが、まだ私は体験していない…
0808デフォルトの名無しさん
垢版 |
2018/06/03(日) 17:34:16.61ID:XweloLai
>>807

ありがとうございます。

>ただヘッダは分割コンパイルにおいて共用するデータだけを書いておくものだから
>ヘッダ List.h に #include <cassert> が含まれているのは、一見、疑問だと思った

ここのところがよく理解できないのですが、

List.h にテンプレートクラス List<T> が書いてあって、
List2.h には List<T> を継承したクラス List2<T> が書いてあります。

そして、List.h, List2.h の両方で assert() を使っています。
0809 ◆QZaw55cn4c
垢版 |
2018/06/03(日) 17:36:57.15ID:5RsKIUxf
>>808
うんうん、なるほど
テンプレートに assert() が含まれているのならば、ヘッダに #include <cassert> が入るのも止むを得ないです
0810デフォルトの名無しさん
垢版 |
2018/06/03(日) 17:47:06.72ID:XweloLai
>>809

ありがとうございました。

また質問で申し訳ないのですが、今度は、全く違う質問になります。

一方向リスト用のセルである Cell<T> というクラスを作りました。
Cell<T> のメンバ変数は、

T data
Cell<T> *next

です。

List<T> には、一方向リストの先頭のセルを指すメンバ変数 Cell<T> *head およびリストに挿入したり、
リストから削除したり、リストのサイズを返したりする様々なメンバ関数があります。

List<T> は一方向リストでしたが、List2<T> は双方向リストにしたいとします。

オブジェクト指向プログラミングでは再利用が重要ということなので、
新たに、双方向リスト用のセルを作るのではなく、 Cell<T> を継承して Cell2<T> というクラスを作ることにします。
Cell2<T> には新たにメンバ変数 Cell<T> *prev を追加します。

List2<T> のほうも List<T> と共通で使えるメンバ関数があるため、再利用したいとします。その場合、気持ちとしては、
List<T> のメンバ変数 Cell<T> *head は無効にして、新たに、 Cell2<T> *head と Cell2<T> *tail をメンバ変数に
したいです。

そして、Cell2<T> に対しても使えるメンバ関数はそのまま使い、双方向リストにしたことにより、より効率的に実装できる
メンバ関数については、オーバーライドしたいです。

上記のようなことをどうやって実現したらよいのか分からないのですが、可能でしょうか?
可能だとして、こういうやり方は非推奨でしょうか?
0811デフォルトの名無しさん
垢版 |
2018/06/03(日) 20:55:43.49ID:E53R3BDh
一方向・双方向リストの、ソースコードを見た方が速い

繰り返しを表す、C++ iterator みたいな、
抽象クラス・インターフェースでも使っているのだろう
0812デフォルトの名無しさん
垢版 |
2018/06/04(月) 08:19:48.74ID:DAGyu3MW
再利用など考えず
一から好きなように双方向リストを作れ

>オブジェクト指向プログラミングでは再利用が重要

は幻想

この場合で言ったらまったく逆で
もともと何か双方向リストがあって、継承して機能制限をして一方向リストに仕立て上げるなら分かるが
一方向リストを継承して双方向リストにするなどイカれてる
0813デフォルトの名無しさん
垢版 |
2018/06/04(月) 09:50:25.37ID:3BCLNr2e
>>810
一方向リストと双方向リストでどれ程共通的な処理があるのか知らんけどCellBase<T>に共通的な処理を定義してそれからCell<T>とCell2<T>を継承させるのが普通じゃね?
0814はちみつ餃子 ◆8X2XSCHEME
垢版 |
2018/06/04(月) 13:04:55.31ID:zKvF3SpI
どうだろう。
総合的な判断が必要という前提はあるけども、
継承が妥当なときの基準のひとつに「is a 関係であるか?」ってのがあるよね。
XはYの一種であると言えるときはXはYを継承していい。
双方向リストは一方向リストの一種であるかというと、まあ Yes って呼んでいいんじゃないの。

ただ、それで楽に使いまわしが出来るかというとそうでもないこともあるので、楽なように作ればいいよ。

練習でやるのなら、使いまわしは置いてそれぞれを作ってみた上で、
共通な部分を探してデザインしなおしてみるというのもいいんじゃないかな。

クラス定義自体は継承関係を持たずにトレイトの方で性質を定義したりとかいったことも今どきはよくやるし、
将来的にコンセプトが入ったらそっちが主流になるかもしれん。
0815デフォルトの名無しさん
垢版 |
2018/06/04(月) 13:18:55.79ID:K9p9OoRg
>>812
もともと何か一方向リストがあって、継承して機能追加をして双方向リストに仕立て上げる
これはダメなん?継承は機能追加ダメなん?
0816デフォルトの名無しさん
垢版 |
2018/06/04(月) 13:19:07.80ID:e7JLMPXe
>>811

ありがとうございました。

>>812

本を見ると再利用が重要と強調されているので、拘ってしまいました。
ありがとうございました。

>>813

ありがとうございました。
0819デフォルトの名無しさん
垢版 |
2018/06/04(月) 14:30:56.26ID:YRbUwbvV
>>810
単方向リストから双方向リストを派生させると、内部構造が違うから相違を埋めるのに面倒臭い事になる
派生した双方向リストから単方向リスト内部のノード列にアクセスできたとしても
単方向リストの状態は単方向でノードが繋がっているのだから双方向リストからどうこうはできない
結局の所、双方向用のノードを単方向用ノードにアップキャストしないと格納できないし、取り出すにはダウンキャストしないといけない
もし何とかして単方向リストに双方向用のノードを双方向に数珠繋ぎ出来たら、そのリストはもう双方向リストだよ
あと、insert()の問題もある、std::forward_listの持つinsert_after()が何故そうなのかは構造的に一目瞭然でしょ
厳密に言えば、std::forward_listはコンテナ要件を満たしていないしな

単方向も双方向もLinked Listとして構造的に似ているが効率的に見ても構造的に見ても別のデータ構造だよ
is-aの関係ですら無いし、再利用ってのはhas-aの関係を考えるべきで、継承は再利用するためのものではないよ
例えば、皆、std::stringをhas-aで利用するよね、std::stackはstd::vectorやstd::listなどのアダプタだよね
0820デフォルトの名無しさん
垢版 |
2018/06/04(月) 16:46:27.38ID:OAwYb5Pt
自分の勉強用だったら、継承した双方向リストクラス作ってみて
「やっぱ普通に作った方が簡単にできたな」って経験をするのもいいと思う
よく「オブジェクト指向はこうだから」って言葉にこだわって面倒くさいことしてる人いるけど
プログラムの基本としては「わかりやすさ」「シンプルさ」こそこだわった方がいいと思うから
将来拡張予定がないプログラムなんかだと無駄な継承しない方がいい
0821 ◆QZaw55cn4c
垢版 |
2018/06/04(月) 19:05:36.84ID:gbEnuF2j
キーワード「継承」もずいぶんと評価が落ちたものですねえ…
0822はちみつ餃子 ◆8X2XSCHEME
垢版 |
2018/06/05(火) 02:58:20.15ID:l2agtc6/
C++ からクラスが無くなることは無いだろうが、
構成の仕方の流行はだいぶん変わってて、
コンセプトが入ったら一気に再編されるかもしれない。

クラスの継承ってそんなに万能じゃないよ。
0823デフォルトの名無しさん
垢版 |
2018/06/06(水) 12:11:26.28ID:ucySJasT
ま、そういうことです
単方向リストを継承して双方向リストにするのは悪手
やってみるまでもなくわかるだろJK
結局ほぼすべてのメソッドを上書きしないといけないから意味ない
しかも一から双方向リストを書いた方が分かりやすいし速い
0824デフォルトの名無しさん
垢版 |
2018/06/06(水) 12:24:14.11ID:ucySJasT
この場合、どうしても手抜きしたかったら
大は小を兼ねるの考えで、双方向リストのみを作って
単方向リストを使う場面でも双方向リストを使えばよい
それがベストだろうというアンサーがちらついてるからこそ、余計に
単方向リストを継承して双方向リストってのが悪手に見えるんよなぁ
余談だけどC++には std::list っていう双方向リストがあるけど単方向リストは提供されてないし
単方向リストなどその程度の扱い、必要ない
0825デフォルトの名無しさん
垢版 |
2018/06/06(水) 15:11:28.97ID:5kytDI4t
>>824
>余談だけどC++には std::list っていう双方向リストがあるけど単方向リストは提供されてないし
std::forward_list など無かった
0826デフォルトの名無しさん
垢版 |
2018/06/06(水) 18:07:41.59ID:9YbuVUhL
>>824
いやあ、単方向リストはそれはそれで使い道はあると思うよ
大体、キャッシュに載り易くメモリ効率も良いstd::vectorで十分だけど
挿入操作を多用するならstd::listやstd::forward_listの方が良いよね
std::forward_listは、std::listよりも要素N個 x ポインタサイズ分のメモリ消費量を抑えられるし
イテレータを使ってO(1)で連続してpush_back()みたいなことも出来る、pop_back()みたいなことはO(1)で出来ないけどね

必要性を問うよりも、その特徴を理解して適切に効率的に使うことが大事なんじゃないかな
まあ、std::mapやstd::setは使うのを躊躇するけどな
O(log n)で値を取り出せて、イテレータでソートされた要素に順次アクセス可能を売りとするけど、メモリ効率が悪すぎる
他の言語のそれらが大体ハッシュテーブルで実装されているのを見るに連想コンテナはunordered系で十分な気もする
0827デフォルトの名無しさん
垢版 |
2018/06/06(水) 19:32:54.16ID:ucySJasT
言葉が足りなくて申し訳ない
俺もリンクリストを使うことは有るけど、大概切迫していてカリカリカスタマイズしたいときに使うものだから
汎用のテンプレートのリンクリストを使ったためしがない
一方向リストなら、なおのこと使わない
0828デフォルトの名無しさん
垢版 |
2018/06/06(水) 20:16:30.41ID:rNkLMN6z
単方向リストを継承して双方向リストを作ることは無いと思うけど、コンポジットすることはあると思う。
ゼロコストの原則の視点に立つと、単方向リストを実装に流用して、双方向リストを作成するのもあり。
0829デフォルトの名無しさん
垢版 |
2018/06/06(水) 20:30:07.38ID:sZLPzbQ0
STLのコンテナにstd::unique_ptr突っ込むと、カスタムアロケーター使えないよな?
0830デフォルトの名無しさん
垢版 |
2018/06/06(水) 20:32:29.81ID:sZLPzbQ0
>>826
O(1)で10個挿入したら、O(1)*10なんだから、結局O(N)じゃないの?
0831デフォルトの名無しさん
垢版 |
2018/06/06(水) 20:34:19.38ID:sZLPzbQ0
もしかして、std::unique_ptrを突っ込むのがすでに間違いで、std::anyを使えってことなんだろうか。
0832デフォルトの名無しさん
垢版 |
2018/06/06(水) 21:03:14.93ID:9YbuVUhL
>>827
std::forward_listとそのイテレータだけでFIFOのQueueを実装できたりするよ
イテレータを介したinsert_after()になるから要素を入れるコストはイテレータのコピー分、std::queueよりも高くなると思うけど
std::queueはstd::dequeかstd::listを利用するから、std::forward_listで実装した方がメモリ使用量は少ない
単方向リストを使用して独自実装した方が低コストに抑えられると思うけどね

まあ、再利用も良し悪しって事だね
0833デフォルトの名無しさん
垢版 |
2018/06/06(水) 21:09:23.87ID:9YbuVUhL
>>830
ごめん書き方が悪かった、1つの要素の挿入にO(1)って意味ね
Linked Listは、挿入場所への移動にO(n)かかり、挿入にO(1)かかるから
最後の要素を指し示すイテレータを保持してたらpush_back()みたいなことも出来るよって話ね
0834デフォルトの名無しさん
垢版 |
2018/06/09(土) 00:34:24.48ID:l0w/1aK3
std::array の empty()メソッドって意味があるのか?と最近思ったので質問させてください
arrayは通常 array<int, 固定値>のように宣言してから使うと思うのですが、
empty()メソッドの戻り値は <int, 0> 以外は全てfalseでした。
つまり通常<int,(0より大きい整数)>で宣言して使う場合empty()はfalseしか返ってこない
気がするのですが、このメソッドは意味があるのでしょうか?
0835デフォルトの名無しさん
垢版 |
2018/06/09(土) 05:56:11.66ID:nuHHgQUg
>>834
テンプレートを使って異なる種類のコンテナに共通に使える処理を書くときに、他のコンテナ達と共通の関数を備えていると都合がいいからかなと思う。
0836デフォルトの名無しさん
垢版 |
2018/06/09(土) 12:31:35.52ID:pc7gEgF8
>>834
そのメンバの存在意味の有無に関わらず、コンテナ要件の1つだからね
他のオブジェクト指向言語でのインターフェイスや抽象クラスを用意していないだけで
コンテナとして共通の要件(インターフェイス)が設けられている
例えば、size()、empty()、begin()、end()など

本来、動的なポリモーフィズムをするためにインターフェイスや抽象クラスを設けるけど
vtableは高コストだから、ゼロオーバーヘッドの原則に則り使用していないのよ
まあ、コンテナ自体STLの1つだからオブジェクト指向的な機能は意識していなかったと思うけどね
余談だが、聞いた所によるとテンプレートって最初マクロで実現しようとしてたらしいね
0837はちみつ餃子 ◆8X2XSCHEME
垢版 |
2018/06/09(土) 12:50:19.63ID:EdmRUNh7
具体的にコンテナに求められる要求はここでまとめられているので参考になれば。
http://ja.cppreference.com/w/cpp/concept/Container

クラスに求める要求を表現するための機能「コンセプト」は C++ の悲願としてずっと前から温められているのだけれど、
なかなか仕様に入らずに先送りされてるという状況。
0838デフォルトの名無しさん
垢版 |
2018/06/11(月) 16:42:05.03ID:SE5SjeC/
ファイルから読み込んだバイト列の先頭部分を参照して、
それがJPEGファイルなのか、PNGファイルなのか、などを判定したいのですが、
どの程度の判定をすればよいものなのでしょうか。
例えばJPEGファイルなら、先頭3バイトを{0xFF, 0xD8, 0xFF}とmemcmp()で十分なのでしょうか。
0840放置された蟻人間 ◆T6xkBnTXz7B0
垢版 |
2018/06/11(月) 16:51:12.74ID:7op9QnGW
画像ファイルには、過去にいくつか脆弱性が確認されている。使用において、脆弱性の存在が致命的ならば、きちんとチェックすべきだし、
処理スピードを優先するなら、memcmpで十分。
0841デフォルトの名無しさん
垢版 |
2018/06/11(月) 17:03:57.96ID:SE5SjeC/
すいません、十分というのは、ファイルの破損や脆弱性関連は置いておいて、
他の形式の正常なファイルも拾ってしまわないかということです。
JPEGの場合、先頭の3バイトを判定すれば、他の正常なファイルが引っかかることはないのでしょうか。
0843デフォルトの名無しさん
垢版 |
2018/06/11(月) 17:12:32.50ID:oqoWhxjw
3バイトをランダムなデータと比較する場合、1/16777216の確率で誤認する
ファイルを最後までパースして、JPEGデータとして読み込めるかどうかチェックするのが確実だが
0844はちみつ餃子 ◆8X2XSCHEME
垢版 |
2018/06/11(月) 17:40:03.88ID:CXPnR3I1
>>841
POSIX には file コマンドがあってファイルの種類を判定できるけど、その実装はヒューリスティックだよ。
参考になるとは思うから読んでみるのもいいんじゃない?
ライセンス的に OK ならそのまま流用してもいいかも。

どの程度の精度で判定すべきかは状況によるので総合的に考えてとしか言えない。
例えば、 jpg ではないファイルが多数ある中から jpg を探すというような状況だったら、
先頭をちょっとだけ読んで jpg っぽかったら全部を読んで詳細に判定するというのでもいい。

ほとんどが jpg なのだったら、いちいち詳細に判定するのは速度的に遅くなるけど、それが許容できるのか、
許容できないのであればどの程度まで緩い判定にしていいのか、バランスの問題。
0847デフォルトの名無しさん
垢版 |
2018/06/12(火) 13:15:57.78ID:BvPEMwcC
明らかに一致しない時は瞬時に判断出来る
ヘッダですぐにわかるので


jpgではあるんだけど
非対応フォーマットとか一部化けてて表示出来ないとか
そういう判断が難しい
0849はちみつ餃子 ◆8X2XSCHEME
垢版 |
2018/06/12(火) 14:45:14.29ID:U9ShKAeR
>>847
えっ? だからまずは先頭をちょっとだけ読んでみる (この判定だと false positive はあっても false negative はない) という話なんだけど。
0850デフォルトの名無しさん
垢版 |
2018/06/12(火) 16:23:32.57ID:LTqXdgcV
元の >>838 の質問に戻れば「どんなファイル群を扱うのかによる」としか
言いようがないんじゃないか?

極端な話、行儀の良いファイルだけなら拡張子で判定しても大丈夫。
(拡張子が間違ってるけど)一般的なファイルばかりなら先頭の何バイトかで判定。

悪意を持って偽装ヘッダや追加情報エリアまで利用してる可能性を気にすれば
JPEGの規格に準拠してるファイルでさえ危険、というレベルまであるかも。
0852デフォルトの名無しさん
垢版 |
2018/06/12(火) 17:43:08.97ID:RH6dhGDk
JFIF以下のJPEG出す機材って監視カメラ以外見たことないなぁ
実運用上はJFIFとEXIF以外は対象外でも良いのかも
0853デフォルトの名無しさん
垢版 |
2018/06/12(火) 17:56:59.93
ポインタでないなら、継承した関数を呼び出すときに、仮想テーブル参照による動的オーバーヘッドはないのですよね?
0854はちみつ餃子 ◆8X2XSCHEME
垢版 |
2018/06/12(火) 18:20:08.25ID:U9ShKAeR
>>853
Yes

それが仮想関数であろうとも、
オブジェクトへのアクセスがポインタ経由でないならば
どの関数を呼び出すのかコンパイル時に確定可能なので、
仮想関数テーブルにアクセスする必要はない。

(はずだと思うが言語仕様での保証はないだろうし、
実態がどうなってるか確かめたことはないんで、
誰かやってみてくれんかな。)
0855デフォルトの名無しさん
垢版 |
2018/06/12(火) 18:35:01.32ID:Q/HiJGFf
>>849
ファイル判別の一般論じゃなくてjpgの判別ですよ
jpgの判別方法を語ればいいんです

文字コードと違ってあやしいとかはなくて
APPnの中数バイト見れば簡単にわかるんですよ
文字でJFIFとかExifとか書いてあるわけなんで

偽装が無いならこれで十分

あとは
対応フォーマットであるのか
正しいフォーマットであるのか
実際にデコード出来るのかどうか
などを判別する必要があるかどうかでその先が決まる
0858はちみつ餃子 ◆8X2XSCHEME
垢版 |
2018/06/12(火) 20:19:36.50ID:U9ShKAeR
>>855
何言ってんの?
その偽装があるかもしれん (ということも想定に入れるかどうは場合による) という話なんだけど。
0860はちみつ餃子 ◆8X2XSCHEME
垢版 |
2018/06/13(水) 01:55:04.01ID:3eXA0K0W
>>859
なるほど、偽装に騙されるのは脆弱性の内 (で、それはないという前提が提示された) という解釈?

判定を誤りうる (データを作れる) のとセキュリティ的な欠陥をなんとなく区別してたけど、
質問者の感じからすると、確かに偽装で騙されるのは脆弱性の内かな。
■ このスレッドは過去ログ倉庫に格納されています

ニューススポーツなんでも実況