質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

2回答

2410閲覧

分割コンパイルについて

ikuo-biyori

総合スコア56

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2017/01/24 21:06

いつもお世話になっています。C言語初心者でただいま勉強中です。マクロを用いて単体テストと結合テストが同じソースコードで行えるようなプログラムを作りたいんですが、マクロを定義してもコンパイル時にmainが2つあって区別できないと怒られます。どのようにすればmainと関数にうまくわけられますか?以下がコードです。

C言語

1コード(ファイル名 main.c) 2 3 4#include<stdio.h> 5#include "header02.h" 6#define SCAN scanf("%d %d",&t.p[i].x, &t.p[i].y) 7//#define PRINT printf("%d %d\n",t.p[i].x,t.p[i].y) 8//#define SYUTU printf("Area = %f\n",calcarea(t)) 9int main()/*コンパイルする時にREADならmain関数の処理*/ 10{ 11 int i; 12 Triangle t; 13 for(i = 0; i < 3; i++){ 14#if defined READ 15 SCAN; 16 #endif/*READの時の処理の最後を実行する*/ 17 // scanf("%d %d",&t.p[i].x, &t.p[i].y); 18 } 19 #if defined WROTE/*gcc -DREAD main02.cのとき*/ 20 // SYUTU; 21 // printf("Area = %f\n",calcarea(t)); 22 printf("Area = %f\n",calcarea(t)); 23 #endif/*READの時の処理の最後を実行する*/ 24 return 0; 25 26} 27/* for component test */ 28double calcarea(Triangle t)/*コンパイルする時にWROTEなら関数の処理*/ 29{ 30 int i; 31 for(i = 0; i < 3; i++){ 32 printf("%d %d\n",t.p[i].x,t.p[i].y); 33 } 34 return 0; 35} 36 37```ファイル名(calc.c) 38```C言語 39#include<stdio.h> 40#include "header02.h" 41int main()/*コンパイルする時にWROTEならmain関数の処理*/ 42{ 43 44 Triangle t = {1,0,0,1,0,0}; 45#if defined WROTE 46#endif 47 #if defined READ/*READの時の処理の最後を実行する*/ 48 printf("Area = %f\n",calcarea(t)); 49 #endif 50 return 0; 51} 52 53double calcarea(Triangle t)/*コンパイルする時にREADなら関数の処理*/ 54{ 55 double area; 56 57 area = (double)((t.p[2].x - t.p[1].x)*(t.p[0].y - t.p[1].y) - 58 (t.p[2].y - t.p[1].y)*(t.p[0].x - t.p[1].x))/2.0; 59 return myabs(area); 60}

コンパイル操作
gcc -c main.c
gcc -c calc.c
gcc main.o calc.o
コンパイルエラー
duplicate symbol _main in:
main02.o
calc02.o
duplicate symbol _calcarea in:
main02.o
calc02.o
ld: 2 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
どうかよろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

main 関数自体を #ifdef 〜 #endif で囲んでください。

投稿2017/01/24 23:08

MasashiKimura

総合スコア1150

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

要するに、main関数が複数定義されているのが問題です。
1つのファイルで1定義でも、複数のファイルをリンクする(まとめる)ときに、複数見つかってしまい、どのmain関数を実行すればよいか分からなくなるので、リンク・エラーが発生します。

対処法は、main関数を1つに絞ることです。
一度コンパイルしてできたコードを、リンクさせるかだけで動作を振り分けるのはすごく難しい(C++なら可能だがCでは不可能?)ので、どうしてもmain関数の書き換えは必要になります。そこで登場するのがマクロです。

現在、calc.cの中にあるmain関数の名前を変えます(calcmainなど)。
次に、main.cの中にあるmain関数に、calcmainを呼び出すコードを書き、calc.cをテストに含める場合のみに定義するマクロ(例えば、LINKCALC_C)を利用して、ifdef/endifで囲みます。

この方法を利用すれば、calc.c以外にファイルを追加する際でもリンクエラーは出なくなります。

投稿2017/01/24 21:53

編集2017/01/25 02:57
majiponi

総合スコア1720

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問