Несколько объявлений [имя переменной]

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

Я использую #ifndef и #def, но похоже, что он все еще компилируется дважды, потому что в процессе компоновки я получаю serveral

multiple declarations of ...

ошибки.

Заголовочный файл PLL

#ifndef PLL_HEADER
#define PLL_HEADER

/********************************************************************
 * includes
 ********************************************************************/
#include "board.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "PITDriver.h"

// Some more stuff

#endif

Вот соответствующие данные журнала

[compiling stuff]

Building target: PLL Function.axf
Invoking: MCU Linker

[other linker stuff]

./source/main.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:45: multiple definition of `accumulateVal'
./source/PLL.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:45: first defined here

./source/main.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:46: multiple definition of `getValOne'
./source/PLL.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:46: first defined here

./source/main.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:47: multiple definition of `getValTwo'
./source/PLL.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:47: first defined here

./source/main.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:48: multiple definition of `countTo'
./source/PLL.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:48: first defined here

./source/main.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:49: multiple definition of `runUntil'
./source/PLL.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:49: first defined here

./source/main.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:50: multiple definition of `currentValue'
./source/PLL.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:50: first defined here

collect2.exe: error: ld returned 1 exit status
make: *** [makefile:39: PLL Function.axf] Error 1

Похоже, у вас, вероятно, есть реальные переменные с хранилищем, расположенным в вашем заголовочном файле. Включить охранников не защитить от этого. Поместите эти переменные в PLL.c и пометьте extern-отмеченными версиями этих переменных в заголовке. Таким образом, оба файла могут ссылаться на переменную, но она существует только в одном месте.

Thomas Jager 29.05.2019 14:23

У вас есть реализовано функция в самом заголовочном файле?

Weather Vane 29.05.2019 14:23
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Исправление сделано по комментарию @Peter

В C вы можете помещать определения переменных в заголовок только в том случае, если он включен только в одну единицу компиляции.

Кажется, у вас есть два модуля компиляции:

  • тот, который компилирует ваши PLL.h и PLL.c для создания PLL.o

  • тот, который компилирует ваш main.c и PLL.h для создания main.o

Оба ваших объектных файла содержат переменные, которые вы определили в PLL.h, и поэтому, когда вы нажимаете на компоновщик, он выдает ошибку, потому что переменные были объявлены дважды (по одному разу в каждом объектном файле).

Чтобы исправить эту ошибку, вы можете либо изменить способ компиляции, либо объединить два модуля компиляции. Или (если вы используете IDE, которая автоматически обрабатывает вашу компиляцию) вы можете применить следующие изменения, чтобы избежать определения переменной в вашем заголовке.

В заголовке: (изменить определение на объявление)

extern int x;

В исходном файле: (определить переменную)

int x;

Наличие определения переменной в заголовке не является запрещенный. Однако заголовок, определяющий переменную, может быть включен ТОЛЬКО в одну единицу компиляции. Если она включена в две или более единицы компиляции, эта переменная будет определена в программе несколько раз. (Согласно стандарту, который дает неопределенное поведение, но на практике это обычно приводит к ошибкам «множественного определения» при связывании).

Peter 29.05.2019 15:37

Спасибо за исправление, я не знал об этом, вы хотите исправить мой ответ или хотите, чтобы я это сделал?

ZeeMoros 29.05.2019 16:13

Другие вопросы по теме