make терпит неудачу с компоновщиком, жалующимся на дубликаты символов - PullRequest
0 голосов
/ 08 января 2019

У меня есть 2 программы C, находящиеся в каталоге с общим заголовочным файлом при выполнении make, компоновщик выдает ошибку для дублированного символа.

cat inventory.h
const char *jpeg_perf_inputs[] = {
    "perf_11k_img_jpg",
    "Sample_jpg_image_1mb_jpg"};

const char *zip_large_input [] = {
    "a.zip",
    "b.zip"
};

uint32_t num_jpeg_perf_inputs = sizeof(jpeg_perf_inputs) / sizeof(jpeg_perf_inputs[0]);
uint32_t num_zip_large_inputs = sizeof(zip_large_input) / sizeof(zip_large_input[0]);

...

cat jpeg_perf_test.c
#include<stdio.h>
#include"inventory.h"
void parse_jpeg_arr(){
for(int i= 0; i<num_jpeg_perf_inputs;i++)
    printf("Image name: %s",jpeg_perf_inputs[i]);
}

cat basic_zip.c
#include<stdio.h>
#include"inventory.h"
void parse_zip_arr(){
for(int i= 0; i<num_zip_large_inputs;i++)
    printf("ZIP file name: %s",zip_large_input[i]);
}

Error

duplicate symbol _zip_large_input in:
    build/posix/obj/apps/integration_apps/zip/jpeg_perf_test.o
    build/posix/obj/apps/integration_apps/zip/basic_zip.o

1 Ответ

0 голосов
/ 08 января 2019

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

Определения принадлежат файлу реализации. Только объявления должны идти в заголовок; Реализации должны идти в отдельный файл:

inventory.h

extern const char *jpeg_perf_inputs[];
extern const char *zip_large_input [];

extern size_t num_jpeg_perf_inputs;
extern size_t num_zip_large_inputs;

inventory.c

#include"inventory.h"

const char *jpeg_perf_inputs[] = {
    "perf_11k_img_jpg",
    "Sample_jpg_image_1mb_jpg"};

const char *zip_large_input [] = {
    "a.zip",
    "b.zip"
};
size_t num_jpeg_perf_inputs = sizeof(jpeg_perf_inputs) / sizeof(jpeg_perf_inputs[0]);
size_t num_zip_large_inputs = sizeof(zip_large_input) / sizeof(zip_large_input[0]);

Заголовка достаточно для компиляции зависимостей, в то время как реализация создает один экземпляр определения для каждого объекта.

Обратите внимание на использование size_t вместо int32_t.

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