"Множественное определение" ошибки компилятора С++
Я не могу избавиться от этих, казалось бы, случайных ошибок компиляции в одном из моих классов.
Я получаю около 4 ошибок, таких как:
multiple definition of `draw_line(float, float, float, float)'
и
multiple definition of `near_far_clip(float, float, float*, float*, float*, float*, float*, float*)'
которые помечены в середине метода.
Я также последовательно получаю multiple definition of `stack'
в середине другого метода. stack
- глобальная переменная в совершенно другом файле. Это даже не упоминается в файле, в котором я получаю ошибку.
Я попытался выделить файл с ошибкой в файлы .h и .cpp(изначально был только .cpp), и ничего об ошибке не изменилось...
У меня нет повторяющихся методов. У меня есть только один #include
of lines.h, и в начале есть предложение #ifndef
. Все эти ошибки появляются в файле .cpp.
Любые идеи, что это может быть?
Хорошо, я получил код вверх:
The lines.cpp - это преобразованный файл .c, полученный мной от моего инструктора. Я включил make файл на всякий случай, потому что у меня всегда были проблемы с ним. Я также аннотировал точно, где ошибки были помечены в файле, но они кажутся довольно случайными, поэтому я не знаю, особенно ли это. Я отказался от файла .h, потому что он ничего не решал и не помогал. Я считаю, что легче будет найти ошибку без нее.
Вот запрошенный файл main.cpp (нет .h).
Я переделаю файл lines.h из-за, и я все еще получаю:
multiple definition of `draw_line(float, float, float, float)'
и
multiple definition of `near_far_clip(float, float, float*, float*, float*, float*, float*, float*)'
в файле lines.cpp, но ошибка multiple definition of `stack'
теперь находится в случайном месте в файле ThreeD.cpp(и теперь она отмечена комментарием). Обновление: Эта ошибка исправлена, и файлы были пересмотрены, чтобы показать это:
Я столкнулся с маркировкой некоторых внешних переменных extern, но это нисколько не повлияло.
Ответы
Ответ 1
Почему вы #include lines.cpp в ThreeD.cpp? Это очень необычно.
Ваш make файл хочет lines.o, поэтому вы собираетесь скомпилировать lines.cpp. Все, что определено в lines.cpp, будет в lines.o, а также в ThreeD.o.
В lines.cpp есть интригующий комментарий:
Don't forget to put declarations in your .h files.
Я думаю, что инструктор хочет, чтобы вы разделили lines.cpp на .h и .cpp.
Выдержка из lines.cpp:
/* These go in your .h file or in lines.h */
/*
Line drawing header.
*/
void draw_line(float, float, float, float);
int near_far_clip(float, float, float *, float *, float *, float *,
float *, float *);
Я подозреваю, что эти два объявления - это единственное, что должно быть в lines.h.
Ответ 2
Вероятно, вы включаете определения функций в файл заголовка. Включите ключевое слово inline
, чтобы они не экспортировались каждым объектным файлом или не помещали их в свой собственный файл .cpp
.
Для вашей глобальной переменной вам нужно использовать ключевое слово extern
в вашем файле заголовка. В противном случае каждый объектный файл экспортирует свою собственную переменную, и компоновщик путается относительно того, какой из них является правильным.
Ответ 3
Пожалуйста, разместите фрагменты кода. Может быть, вы определяете свои методы как в объявлении класса, так и снаружи?
class X {
void foo(); // No definition, just declaration
void bar() {} // Declaration + definition
};
void X::foo() {} // First Definition, OK
void X::bar() {} // Already defined, ERROR
Ответ 4
Проверьте, включают ли охранники в орфографическую ошибку.
Проверьте свои параметры make, возможно, кто-то скомпилирован в несколько объектных файлов.
Попытайтесь исключить части файлов и кода, пока не найдете причины ошибок.
Редакция:
fix включают *.cpp файлы. Они должны быть связаны.
Ответ 5
Как уже было сказано, недостаточно информации для правильной диагностики здесь.
Но если draw_line
и др. определены в файле заголовка, а не в исходном (cpp) файле, у вас могут быть методы, которые предположительно объявляются как встроенные в заголовочном файле, которые на самом деле не правильно вставляются. В этом случае каждый .cpp файл, который включает заголовок, генерирует собственное определение функции draw_line
и генерирует предупреждения во время связи.
Это может произойти, если вы используете макроС#defined INLINE, который поступает из забытого или удалённого системного заголовка, и по какой-либо причине INLINE получает предварительную обработку в никуда.
например:.
//Lines.h
#define GCCC //Note the typo
#if defined(GCC)
#define INLINE inline
#elif defined (MSVC)
#define INLINE __inline
#else
#define INLINE //Due to the typo, INLINE will be turned into nothing
#endif
INLINE void draw_line(float x1, float y1, float x2, float y2)
{
//Draw the line
}
//File1.cpp
#include "lines.h" //will define draw_line
//File2.cpp
#include "lines.h" //will also define draw_line
И связывание File1.cpp и File2.cpp приведет к появлению нескольких ошибок объявления
Ответ 6
#ifndef THREED_H_
#define THREED_H_
#endif /* THREED_H_ */
удалить или прокомментировать эти строки, и это сработало для меня
Ответ 7
Ошибки с множественным определением - это ошибки компоновщика, но без дополнительной информации сложно их диагностировать. Проверка того же файла не отображается дважды в команде компоновщика и что ваши файлы заголовков содержат только объявления, определения.
Ответ 8
Не видя кода, вам действительно не помогает. Компилятор четко заявляет о противоположности вам (существует хотя бы одно дублирующее определение).
Попробуйте воспроизвести ошибку с минимальным примером. Вы пробовали компилировать код вне Eclipse в командной строке? С каким результатом?
Ответ 9
Привет, Что я вижу здесь, что основное правило применяется для ll. Я объясню, как все работает в таких ошибках и что происходит:
Возьмем один пример "Создание глобальной переменной"
Не путайте файл заголовка для файла cpp.
Заголовок доступен только для того, чтобы несколько файловых проектов имели общий
интерфейс
перед связыванием.
Элемент 1.List
Вы должны указать информацию о глобальной переменной в заголовке:
extern int Var_Global;
-
Элемент списка
while keeping the Actual code in the
cpp :
int Var_Global;
И убедитесь, что вы 1. включите заголовок и 2. соедините код.
Свяжите код один раз и один раз, и есть только одна копия данных,
поскольку вы можете включать заголовки в течение всего дня, это говорит о другом коде, который
будет копия данных во время соединения.
Я вижу много людей, которые вводят код в файлы заголовков, в то время как это может работать
в некоторых случаях, это плохая привычка вступать и рано или поздно вызывать проблемы или
позже.
Привет,
Prashantap >