Ошибка связывания с «множественным определением» ошибки компиляции - PullRequest
6 голосов
/ 29 января 2012

У меня есть следующий заголовок "константы":

/* constants.h */

#ifdef __cplusplus 
extern "C" {
#endif

#pragma once

#ifndef CONSTANTS_H
#define CONSTANTS_H

const char * kFoo = "foo";
const char * kBar = "bar";

#endif

#ifdef __cplusplus
}
#endif

Я #include -ю заголовок в файлах X.c и Y.c.

Обратите внимание, что я не , включая это в X.h или Y.h.

Файлы X.c и Y.c компилируются в объектные файлы, которые архивируются в статическую библиотеку с именем libXY.a.

Когда я включаю X.h и Y.h в Z.h и когда я ссылаюсь на libXY.a, я не могу скомпилировать Z.c без ошибок:

/* Z.h */

#include "X.h"
#include "Y.h"

Я получаю следующие ошибки компиляции при попытке компиляции Z.c:

/path/to/libXY.a(X.o):(.data+0x0): multiple definition of `kFoo`
/path/to/libXY.a(Y.o):(.data+0x0): first defined here
/path/to/libXY.a(X.o):(.data+0x8): multiple definition of `kBar`
/path/to/libXY.a(Y.o):(.data+0x8): first defined here

Я попытался установить kFoo и kBar на extern, но это не помогает.

Как мне разрешить несколько определений, если я включаю константы только один раз (через защиту заголовка #ifndef CONSTANTS_H)?

Ответы [ 2 ]

9 голосов
/ 29 января 2012

Как мне разрешить несколько определений, когда я включаю константы только один раз (через защиту заголовка #ifndef CONSTANTS_H)?

С этим в constants.h:

const char * kFoo = "foo";

определение для kFoo будет передаваться в каждом переводе, который #include s constants.h. Таким образом, несколько определений, которые затем приводят к ошибкам ссылки.

Как заметил Асаэль (+1), вы бы решили это так:

constants.h

extern const char* const kFoo;

constants.c

const char* const kFoo = "foo";

(обратите внимание, что я также сделал указатель const, который обычно что вы хотите сделать в этом случае)

4 голосов
/ 29 января 2012

Вы не должны определять переменные в заголовочном файле.определите их в одном из исходных файлов и объявите их (extern) в заголовочном файле.

(Вы писали: «Я пытался установить kFoo и kBar в extern, но это не помогает».думаю, вы не определили их в исходном файле)

...