プログラミングなどなど

プログラミングに関係しそうな内容を

GCC:関数重複定義(Multiple Definition)を-z muldefsで許可する

同僚の方が一時的な確認のために同名の関数を静的リンクした実行ファイルを作成しようとしてエラーになっていました。C言語ではできないんじゃないかな。と思っていたのですが、「HPではできたのに〜」と言っていたのを聞き、ならばGCCでもオプションでどうにかなるのではと思って調べてみました。

結果、リンクオプション -z muldefs を利用することで可能でした。
使用したファイルは以下となります。

func.h

簡易的にするためインクルードガードは省いています。

int func(int x);

func01.c

#include "func.h"

int func(int x)
{
  return x + 10;
}

func02.c

#include "func.h"

int func(int x)
{
  return x + 100;
}

main.c

#include <stdio.h>
#include "func.h"

int main(void)
{
  int x = func(10);

  printf("func(10) = %d\n", x);

  return 0;
}

通常のコンパイル

普通にコンパイルしてみます。

$ gcc -Wall main.c func01.c func02.c 
/tmp/ccKwhV9A.o: 関数 `func' 内:
func02.c:(.text+0x0): `func' が重複して定義されています
/tmp/ccGuOvnL.o:func01.c:(.text+0x0): ここで最初に定義されています
collect2: error: ld returned 1 exit status

funcが重複してリンクが失敗しています。

マニュアルにあたる

ldのマニュアルを見ると -zオプションのキーワードを指定すると重複定義を許可してくれそうです。(ld --helpでも見つけられました。)

$ man ld
:
       -z keyword
           The recognized keywords are:
:
           muldefs
               Allow multiple definitions.

リンクオプション -z muldefsを試してみる

リンク時のエラーが解消されています。また、今回試した例では、左側の定義が有効になっているようです。

$ gcc -Wall -z muldefs main.c func01.c func02.c 
$ ./a.out 
func(10) = 20
$ gcc -Wall -z muldefs main.c func02.c func01.c 
$ ./a.out 
func(10) = 110