up:: Cpp
他のソースファイルを読み込む機能。
Cppビルド
まずcppのビルド仕組みから。
プリプロセッサでコメント削除やプリプロセッサディレクティブの処理といった変形、
コンパイラでアセンブリ翻訳、
アセンブラで機械語翻訳、
リンカでソースを一つにまとめる。
includeの書式は#include "name.hpp"
でありプリプロセッサディレクティブ。
つまりプリプロセッサで置き換え処理される対象。
余談
#include<>
と#include””
は検索対象が違う。
<>
は処理系のincludeパスから、""
は(一般的には)まずカレントディレクトリで対象ファイルを検索、見つからなければ処理系を見る。
処理系パスは.vcxproj
、もしくは構成→C++→全般→追加のインクルードディレクトリで変更可能。g++なら-I
オプション。
問題
単純な置き換え処理ながら、その全てがコンパイラで翻訳されるため様々な問題が発生する。
One Definition Rule
略してODR。
関数は複数宣言しても構わないが、複数定義するとエラーになる。
#include
は単純置き換えであるため、例えば読み込むヘッダファイルに一緒に関数定義を書き込んで、複数ファイルでincludeするとエラーになる。
ここは従来でも回避法があった。
プリプロセッサディレクティブを駆使し二回目のincludeを防ぐアイデア。いわゆるインクルードガード。弾いてしまっても最後はリンカでくっつけるので問題ない。
#ifndef
で単純に弾くタイプと、#pragma once
という拡張機能を使うタイプがある。大体後者。
名前衝突
ODRと似たようなものだが、標準ライブラリをusingで読んだりすると中身の関数名が予約され使えなくなる。
これを他のファイルで読み込むと、そのファイルでも予約され使えなくなる。using namespace stdがいい例。
読み込み順によるエラー
読んで字のごとく。
遅い
最大の問題。
全部コンパイラ翻訳するのでクソ長い。
ここを解決したのがmodule。