Boost. 勉強会 #6 札幌 ( 2011-11-05 ). 概要  主に cppll ML でご紹介してきた tips を C++ の仕様をより掘り下げた形でまとめ直し てみました。  今回は #include にフォーカスした内容です。 C++ Tips 1 #include 編 Boost.

Slides:



Advertisements
Similar presentations
C 言語講座第 5 回 構造体. 構造体とは ... 異なる型の値をまとめて新しい型とする 機能がある . つまり , 複数の変数を 1 つのまとまりにできる . 配列と違って同じ型でデータをまとめるのではな く違った型のデータをまとめられる .
Advertisements

2.5 プログラムの構成要素 (1)文字セット ① ASCII ( American Standard Code for Interchange ) JIS コードと同じ ② EBCDIC ( Extended Binary Coded Decimal for Information Code ) 1.
1 第5回 配列. 2 今回の目標 マクロ定義の効果を理解する。 1次元配列を理解する。 2次元配列を理解する。 ☆2 × 2の行列の行列式を求めるプログラ ムを作成する.
プログラミング言語論 第10回(演習) 情報工学科 木村昌臣   篠埜 功.
プログラミングとは Q.プログラムとは何か? A.コンピュータを制御するための,コンピュータに対する命令(指示)の集まり.
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第5回 関数(1) 情報・知能工学系 山本一公
2015年度 プログラミングⅡ ~ Cプログラミングやってみよう ~.
応用理工学情報処理 第1回(2015年10月 5日) 月曜日担当 前島展也 Manaba
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
UNIXマシン間のファイル転送 2002年10月20日 海谷 治彦.
第12回構造体.
システムプログラミング 第5回 情報工学科 篠埜 功 ヒアドキュメント レポート課題 main関数の引数 usageメッセージ
C++ むかしばなし episthmh わんくま同盟 Microsoft MVP for
OSとコマンド OS:コンピュータを使うための基本プログラム コマンド:OS上で使用できる命令 OS本体であるカーネルの内部コマンド
プログラミングとは Q.プログラムとは何か? A.コンピュータを制御するための,コンピュータに対する命令(指示)の集まり.
プログラミング演習II 2004年10月19日(第1回) 理学部数学科・木村巌.
マスタリング バベル Boost.勉強会 #2 ( ).
Boost.勉強会 #8 大阪 ( ) C++ Tips 3 カンマ演算子編.
補足説明.
情報工学科 3年生対象 専門科目 システムプログラミング 第5回、第6回 ヒアドキュメント レポート課題 情報工学科 篠埜 功.
図書館職員のための アプリケーション開発講習会
暗黙的に型付けされる構造体の Java言語への導入
第10回関数 Ⅱ (ローカル変数とスコープ).
独習XML 第2章 XML文書の構成要素 2.1 XMLの文字と文字列 2.2 コメント
コンピュータ系実験Ⅲ 「ワンチップマイコンの応用」 第1週目 アセンブリ言語講座
プログラミング演習I 2003年6月25日(第10回) 木村巌.
ソフトウェア制作論 平成30年10月3日.
プログラミング入門2 第11回 情報工学科 篠埜 功.
復習 前回の関数のまとめ(1) 関数はmain()関数または他の関数から呼び出されて実行される.
プログラミング言語論 第五回 理工学部 情報システム工学科 新田直也.
アルゴリズムとデータ構造 補足資料5-1 「メモリとポインタ」
Fortranについて 高エネルギー加速器研究機構 平山 英夫.
岩村雅一 知能情報工学演習I 第12回(C言語第6回) 岩村雅一
1-3 UMLの図(ダイアグラム) コンポーネント図 システムの物理的な構成を表現 ソフトウェアコンポーネントの依存性を表現
コンパイラ 2011年10月20日
情報基礎演習I(プログラミング) 第11回 7月12日 水曜5限 江草由佳
B演習(言語処理系演習)第2回 田浦.
C言語 はじめに 2016年 吉田研究室.
ファイルの読み込み, ファイルからのデータの取り出し, ファイルの書き出し
プログラムの差分記述を 容易に行うための レイヤー機構付きIDEの提案
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
Make の使い方.
標準入出力、変数、演算子、エスケープシーケンス
Visual Studio 2013 の起動と プロジェクトの新規作成 (C プログラミング演習,Visual Studio 2019 対応) 金子邦彦.
モジュール分割.
コンパイラ 2012年10月11日
情報工学科 3年生対象 専門科目 システムプログラミング 第3回 makeコマンド 動的リンクライブラリ 情報工学科 篠埜 功.
岩村雅一 知能情報工学演習I 第12回(後半第6回) 岩村雅一
情報工学科 3年生対象 専門科目 システムプログラミング 第3回 makeコマンド 動的リンクライブラリ 情報工学科 篠埜 功.
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
Cp-1. Microsoft Visual Studio 2019 C++ の使い方 (C プログラミング演習,Visual Studio 2019 対応) 金子邦彦.
全体の流れ 画像ファイルを開き,画像データをメモリ上にロード メモリ上にロードした画像データに処理を加える
プログラミング言語論 第九回 理工学部 情報システム工学科 新田直也.
オブジェクト指向言語論 第七回 知能情報学部 新田直也.
プログラミング言語論 第九回 理工学部 情報システム工学科 新田直也.
オブジェクト指向言語論 第七回 知能情報学部 新田直也.
情報処理Ⅱ 2005年11月25日(金).
プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ, 情報処理言語Ⅰ(実習を含む。)
情報処理Ⅱ 第9回:2003年12月16日(火).
プログラミング演習II 2003年11月19日(第6回) 木村巌.
プロジェクト演習III,V <インタラクティブ・ゲーム制作> プログラミングコース
第4回 配列.
情報処理Ⅱ 小テスト 2005年2月1日(火).
printf・scanf・変数・四則演算
C++ むかしばなし episthmh わんくま同盟 Microsoft MVP for
C++ むかしばなし episthmh わんくま同盟 Microsoft MVP for
第5回 配列.
岩村雅一 知能情報工学演習I 第7回(後半第1回) 岩村雅一
プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ, 情報処理言語Ⅰ(実習を含む。)
第1章 文字の表示と計算 printfと演算子をやります.
Presentation transcript:

Boost. 勉強会 #6 札幌 ( )

概要  主に cppll ML でご紹介してきた tips を C++ の仕様をより掘り下げた形でまとめ直し てみました。  今回は #include にフォーカスした内容です。 C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 2

C++ Tips

#include ってなに?  指定されたファイルの内容を #include 指令の 記述の位置に展開する機能です。  コンパイルの直前にプリプロセスによって展開さ れます。  コンパイラに対して展開するのであって元のファ イルは書き換わりません。  ISO/IEC では 2003 年版および 2011 年版とも に §16.2 Source file inclusion ( JIS X 3014 では「ソー スファイルの取込み」 ) で記述されています。 C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 4

#include ってなに? C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 5 【 a.h 】 inline int nabs(int a) { return 0 <= a ? -a: a; } 【 a.cpp 】 … #include "a.h" int main() {... } 【展開結果】 … inline int nabs(int a) { return 0 <= a ? -a: a; } int main() {... }

#include ってなに?  Java の import や C# の using とは似て非な るモノです。  最近の他言語の類似した機能とその本来の目 的は似たようなものなのですが、 C および C++ の #include 指令は仕様上、プリプロセスによっ てただ機械的に指定されたテキストファイル をその場所にぶちまけるだけです。 C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 6

#include ってなに?  cpp コマンドを使って #include の展開結果 を確認すると #line 指令も挿入されます。  この #line 指令によりコンパイルエラーの位置 情報や __FILE__, __LINE__ といったマクロが展 開前の位置で指し示されるようにします。 C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 7

#include ってなに? C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 8 【展開結果】 … // ←a.cpp の 19 行目だとします。 #line 1 "a.h" inline int nabs(int a) { return 0 <= a ? -a: a; } #line 20 "a.cpp" int main() {... } 【 a.h 】 inline int nabs(int a) { return 0 <= a ? -a: a; } 【 a.cpp 】 … #include "a.h" int main() {... }

#include ってなに?  プリプロセスは #include 指令以外にも #define 指令や #if 指令などを処理します。  他のヘッダファイルに依存しているヘッ ダファイルは必ずその依存先のヘッダ ファイルを #include しておきましょう。  これをちゃんとやっておかないとメンテナン ス性が著しく低下します。 C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 9

#include ってなに?  #include する時の と "hoge.h" の違い  ファイル探索範囲に AとBがあったとして、 は A しか見ないが、 "hoge.h" はまず B を見た上で見つからな かったら A からもファイルを探す。  ただし B はそもそも存在しないことも許されており、その場 合、ファイル探索範囲の違いはなくなる。  A と B のファイル探索範囲およびその指定方法は処理系依存。  一般的には時の は標準ライブラリおよび処理系に 組み込んだライブラリのヘッダを読み込む場合に使用され、 "hoge.h" はユーザープログラムのヘッダを読み込む場合に使 用されます。 C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 10

#include ってなに?  ファイルの指定に利用可能な文字列の種類については ISO/IEC の 2003 年版では §2.8 Header names 、 2011 年版 では同名の §2.9 ( JIS X 3014 では「 §2.8 ヘッダ名 」 ) で記述 されています。  ISO/IEC の 2003 年版では §2.2 Character sets 、 2011 年版では同 名の §2.3 ( JIS X 3014 では「 §2.3 文字集合 」 ) も参照のこと。  簡単且つ乱暴にまとめると ASCII 文字 ( タブや改行も含む ) は使ってい いけど、日本語を直接使用するのはダメで、国際文字名を使いた い場合は \uXXXX あるいは \UXXXXXXXX の形式で指定。 ( X は 16 進数 文字 )  例外としてヘッダ名を で囲む場合は > が、二つの " で囲む場 合は " が使えない。 C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 11

インクルードガード  依存関係にあるヘッダファイルをヘッダ ファイル内で #include していると、複数の ヘッダファイルを #include した際に、共通 で依存関係にあるヘッダファイルの #include が重複し、コンパイラからすると その中で行われる定義も重複することに なりエラーになってしまいます。 C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 12

インクルードガード C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 13 【展開結果】 inline int nabs(int a) { return 0 <= a ? -a: a; } inline int nabs(int a) { return 0 <= a ? -a: a; } 【 a.h 】 #include "c.h" 【 a.cpp 】 #include "a.h" #include "b.h" 【 b.h 】 #include "c.h" 【 c.h 】 inline int nabs(int a) { return 0 <= a ? -a: a; } 定義が重複してしまいエラーになる!

インクルードガード  そこで出てくるのがインクルードガード と呼ばれるテクニックです。  #if 指令と #define 指令を使って2つ目以 降は展開されないようにします。 C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 14

インクルードガード C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 15 【中間展開イメージ】 #if !defined(c_h) #define c_h inline int nabs(int a) { return 0 <= a ? -a: a; } #endif #if !defined(c_h) ここは #if の条件が成立しないので展 開されない。 #endif 【 c.h 】 #if !defined(c_h) #define c_h inline int nabs(int a) { return 0 <= a ? -a: a; } #endif 【最終展開イメージ】 inline int nabs(int a) { return 0 <= a ? -a: a; }

インクルードガード  インクルードガードで #define するマクロは名前 はなんでもいいのですが他と名前が被るといろ いろまずいことが起きることが予想されますの で、まず被らないだろうって名前にする必要が あります。  #include される側ではなく #include する側でイン クルードガード行うこともあります。  #include する側でインクルードガードするのをどこか でうっかり忘れてしまうリスクがあるので多用はされ ていないようですが。 C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 16

インクルードガード C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 17 【 a.h 】 #if !defined(c_h) #define c_h #include "c.h" #endif 【 b.h 】 #if !defined(c_h) #define c_h #include "c.h" #endif

インクルードガード  拡張仕様で #pragma once と記述しておく だけでインクルードガードをやってくれ るコンパイラもあります。 C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 18

インクルードガード C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 19 【 c.h 】 #pragma once inline int nabs(int a) { return 0 <= a ? -a: a; } 【 c.h 】 #if !defined(c_h) #define c_h inline int nabs(int a) { return 0 <= a ? -a: a; } #endif

インクルードガード :: 使い分け  コンパイルの速度的には #pragma once や #include する 側で行う手製インクルードガードがよいとされていま す。  移植性の面では #include される側で行う手製インク ルードガードがベストです。  直接は手を入れたくないあるいは手を入れられない第 三者から提供されるヘッダファイルにインクルード ガードが施されていない場合は #include する側で行う 手製インクルードガードしかありません。  手製インクルードガードでラップしたヘッダファイルを使 うのもありです。 C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 20

インクルードガード :: 補足  定義だから重複エラーになるのであって、 宣言だけなら重複エラーになりません。 C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 21

意図的な再インクルード  ヘッダファイルでいろいろな小細工をしたい場合に意 図的に再インクルードさせる場合などもあります。  躊躇無く複数のヘッダファイルを使える状況下ではまず必 要になることはないテクニックです。  このテクニックを利用する場合、 #pragma once などに頼ら ず自前で且つ適切にインクルードガードを行う必要があり ます。  特定のマクロ群の On/Off を切り替えさせる為。  ひとつのヘッダファイルに複数の機能を持たせる為。  マクロの指定により異なる内容のヘッダファイルのように振 る舞わせたり。 C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 22

ソースファイルのインクルード  C++ のテンプレートの機能を使ったコード を書くと一般的にはソースファイルに書 くべきコードまでヘッダファイルに書か ざるを得ませんが、ソースファイルを ヘッダファイルから #include することで、 形だけは従来どおりにヘッダファイルと ソースファイルへ書き分けることができ ます。 C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 23

データファイルのインクルード  移植性が高く且つ超お手軽なデータ埋め 込み方法としても #include は使えます。 C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 24

データファイルのインクルード C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 25 … int data[] = { #include "data.csv" // 42,42,42, }; …

ストリームのインクルード  役に立つことはまずないですが /dev/tty (linux) だの con (windows) だのといったスト リームをインクルードすることも可能で す。  プロンプトの類いが出せないのが辛いところ です。 C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 26

ストリームのインクルード C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 27 … int confidential_value = // この値はコンパイル時に手入力する。 #if defined(__WIN32__) || defined(_WIN32) #include #else #include #endif ; …

#include __FILE__ について  そのファイル自身をインクルードしよう として #include __FILE__ とするのは構文 的は間違いではないが、規格上も実際も #include で指定する形式と __FILE__ が一 致している保証がなく、またカレント ディレクトリの扱いが処理系によって異 なる問題もある為、規格的には有効に機 能する保証はない。 C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 28

#line  明示的に利用することで次のようなことができます。  コンパイル環境の物理的なファイルパスの隠蔽。  __FILE__ がどのような形のナロー文字列になっているのかは処理系依存。  ユーザー名が含まれるパスでコンパイルして実行形式ファイルに __FILE__ と して埋め込まれる事態を防げます。  同じファイル内でのブロックの明示。  __function__ 疑似マクロなどが使える場合はあまりその必要性はありません が。  #line で指定できる行番号は C++03 だと 1 ~ 32,767 の範囲で C++11 だ と 1 ~ 2,147,483,647 の範囲になります。この値域から外れる数値が 指定された場合の動作は未定義となります。  ISO/IEC では 2003 年版および 2011 年版ともに §16.4 Line control ( JIS X 3014 では「行制御」 ) で記述されています。 C++ Tips 1 #include 編 Boost. 勉強会 #6 札幌 29

C++ Tips 1 #include 編