C: дубликаты символов для архитектуры x86_64 - PullRequest
0 голосов
/ 22 ноября 2018

Я пытаюсь создать структуру в заголовочном файле и инициализировать структуру шаблона.По какой-то причине при включении файла заголовка в несколько файлов выдается следующая ошибка:

gcc foo.c bar.c -o foo -Wall

duplicate symbol _MYFOO in:
    /var/folders/s4/zyw5lgk92wj9ljnsypgwdccr0000gn/T/foo-52f8fc.o
    /var/folders/s4/zyw5lgk92wj9ljnsypgwdccr0000gn/T/bar-6dc21f.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Это мои файлы: Bar.c:

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

void helloWorld() {
    printf("Hello world\n");
}

Bar.h

typedef struct Foo Foo;

struct Foo {
    int number;
} MYFOO = {2};

void helloWorld(void);

Foo.c

#include "bar.h"

int main() {
    helloWorld();
}

Интересно, что при удалении строки, содержащей

MYFOO = {2};

Код компилируется и работает отлично.Я считаю, что это связано с включением Bar.h дважды, что в итоге включает в себя эту структуру дважды?Но как мне избежать чего-то подобного?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 02 декабря 2018

Поработав еще немного, я нашел причину ошибки из строки MYFOO = {2};

Это было связано с тем, что я инициализировал структуру в моем заголовочном файле. Заголовочные файлы предназначены для определений, а не для инициализации. Вместо этого, решением проблемы было просто определить и инициализировать строку в соответствующем исходном файле Foo.c.

Теперь, в этомфайл, который я включил в качестве глобальной переменной:

Foo MYFOO = {2};

Теперь, чтобы получить доступ к этой переменной в любом другом файле, например, в моем Bar.c, все, что мне нужно было сделать, это включить строку

extern Foo MYFOO;

Это решило мою проблему для компиляции и означало, что я мог использовать структуру в других файлах по своему усмотрению!

0 голосов
/ 22 ноября 2018

Вы можете добавить директиву в файл Bar.h, чтобы проверить, был ли файл уже включен:

#ifndef _BAR_H_INCLUDED_
// Bar.h not included - declare your structs, etc, here.

// Define _BAR_H_INCLUDED_ to indicate this file has already
// been included
#define _BAR_H_INCLUDED_ 1
#endif

Это должно как минимум помешать вам включить Bar.h несколько раз.

РЕДАКТИРОВАТЬ

Лучшим решением может быть включение Bar.c из Bar.h:

// Bar.h
#ifndef _BAR_C_INCLUDED_

// code here

// Include Bar.c
#include "Bar.c"
#define _BAR_C_INCLUDED_

#endif

Затем вы можете просто включить Bar.h в Foo.c:

// Foo.c

#include <stdio.h>
#include <stdlib.h>

#include "Bar.h"

int main() {
    //...

Затем скомпилировать:

gcc Foo.c -o Foo

Итак, вот ваш обновленный код - сначала Bar.h

#ifndef _BAR_C_INCLUDED_

typedef struct Foo Foo;

struct Foo {
    int number;
} MYFOO = {2};

void helloWorld (void);

#include "Bar.c"
#define _BAR_C_INCLUDED_

#endif

Сейчас Bar.c:

void helloWorld() {
    printf("Hello world\n");
}

Наконец, Foo.c - включите сюда stdio.h, а также Bar.h (что, в свою очередь, включает Bar.c для нас):

#include <stdio.h>

#include "bar.h"

int main() {
    helloWorld();
}

Идля компиляции:

gcc Foo.c -o Foo -Wall
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...