私はここ数年、C++開発にVIMを使用していますが、IDEまたは強力なテキストエディタを使用するかどうかについては、議論したくありません。ソフトウェア開発。これまで私は、すべてがテンプレートであるかインラインで宣言されているヘッダーのみのテンプレートライブラリに主に関与してきました。したがって、.cppファイルは主要な役割を果たしません。
最近、私は「従来の」C++開発にもっと関わり、ヘッダー/非ヘッダーファイルの同期という古い問題に直面しています。 makeターゲットで使用したり、このジョブを処理するためにVIMに統合したり、.cppファイルに基づいてヘッダーファイルを更新したりできるコマンドラインツールがあるかどうか疑問に思っています。基本的に、クラス/構造または(テンプレートおよびインライン)実装の宣言はヘッダーファイルでは無視する必要がありますが、関数宣言は.cppファイルに基づいて追加、削除、または更新する必要があります。
lzz ツールを知っていますが、実際に追加の3番目のファイル形式でコーディングし、実際にコンパイルする前に.h /.cppファイルに前処理する必要があります。
その仕事をすることができる何かが周りにありますか?他の非IDE開発者はこの問題をどのように処理しますか?
私自身、最初の質問への回答に非常に興味がありますので、残念ながらここでは良いアドバイスをすることはできません。
少なくとも2番目の質問に答えるには、これは、同期していないヘッダーファイルで欠落している宣言を手動で追加したり、変更された宣言を調整したりするために使用する、やや半自動の方法です。
警告を有効にして(!)コンパイラを使用して、欠落/変更された宣言を見つけます。
関数定義のシグネチャを変更した後、gcc
は次のようなエラーをスローします。
error: conflicting types for ‘....’
note: previous declaration of ‘....’ was here
定義への参照と対応する宣言の両方がすでにエラーメッセージに示されているため、これを修正するのは比較的簡単です。
私はemacs
ユーザーなので、これがvi
で行われる方法を説明することはできませんが、この場所に自動的にジャンプする同様に簡単な方法があると確信しています。実行する必要があるのは次のとおりです。
場所にジャンプ1行をコピー
場所2にジャンプし、古い行をコピーに置き換えて、末尾に;
を追加します。
一方、対応するヘッダーファイルにプロトタイプを追加せずに新しい関数が追加された場合、gcc
は次のようなものをスローします。
warning: implicit declaration of function ...
これを修正すると、タグテーブルが役立ちます。繰り返しますが、これがvi
でどのように処理されるかはわかりませんが、コンパイラの警告でその名前で指定された関数定義にすばやくジャンプする方法があると確信しています。
ここでのワークフローは次のようになります。
関数にジャンプ....の定義、行をコピー
ヘッダーファイルに切り替え、行を貼り付けて、末尾に;
を追加します
この方法は洗練されたものではありませんが、ヘッダーを調整してソースファイルと同期するのを忘れた場合に機能することがわかりました。これは、数回のキーストロークで実行できます。
ここで例を挙げてそのアプリケーションを示すために、ヘッダーを修正する必要がある最小限のプログラムを示します。
/* main.c */
#include "add.h"
int main (int argc, char *argv[]) {
int a=0, b=0;
add (a, b);
sub (a, b);
return 0;
}
関数add
とsub
はどちらも、以下に示すadd.c
で定義されています。
/* add.c */
#include "add.h"
int add (int a, int b) {
return a + b;
}
int sub (int a, int b) {
return a - b;
}
犯人add.h
は、関数add
の署名の不一致と、関数sub
の宣言の欠落の両方を示しています。
/* add.h */
long add (long a, long b);
コンパイルしようとすると、次のようになります。
gcc -Wall main.c add.c
main.c: In function ‘main’:
main.c:7: warning: implicit declaration of function ‘sub’
add.c:3: error: conflicting types for ‘add’
add.h:2: note: previous declaration of ‘add’ was here
最初の問題:
main.c:7: warning: implicit declaration of function ‘sub’
sub
の宣言がadd.h
にないという事実によるものです
適切な署名を見つける:
sub
の定義にジャンプしますここまでは、介入が必要なかったため、キーボードマクロによってすべての手順を自動的に実行することもできました。次の部分は手作業で行う必要があります。
「正しい」ヘッダーファイルと「正しい」場所の選択は、これまでに行った手順とは対照的に、おそらく好みの問題であるため、ここで可能な自動化はあまりないと思います。
最後のステップは、コピーした署名を貼り付けることです。
{
を;
に置き換える次に、add
s宣言と定義の不一致を修正する必要があります。
add.c:3: error: conflicting types for ‘add’
add.h:2: note: previous declaration of ‘add’ was here
定義から新しい署名をコピーするには:
宣言を置き換えるには:
{
を;
に置き換える2つのバッファがポップされたので:
ご覧のとおり、時間のかかるプロセスではありませんが、このアプローチを使用して宣言の欠落や誤りを修正するために絶えず前後にジャンプすることは、依然としてかなり退屈な作業です。最初の実行でタイプミスまたは完全に欠落した宣言を修正するためにのみ使用します。
「正しい」宣言を手動でヘッダーに配置することは、今でも私がとる主なアプローチです。
実装する前にAPIをレイアウトすることは、私見では最悪の考えではないかもしれないので、この戦略はそれほど悪い選択であってはなりません。
UNIXタイプのシステムでは、通常、IDEはこのジョブを処理しません(私の経験では)。ビルドツール(通常、Eclipse、EmacsなどのIDEにはバンドルされていません)がこの作業を行います。
最近のシステムでは、これを処理する最良の方法は、コンパイラにそれを行わせることです。結局のところ、コンパイラは最もよく知っています。 GCCおよび他のほとんどのUNIX/POSIXコンパイラには、ソースファイルのコンパイル中にmakeスタイルの依存関係宣言を発行するオプションがあります。これをmakefileに配置してから、出力ファイルをmakefileに含めるだけで、すべてが非常にうまく機能します。
たとえば、次を参照してください。 http://make.mad-scientist.net/autodep.html
次に、-MMD -MP
などのGCCオプションを確認します(これらはプリプロセッサオプションです)。