странные переопределенные символы - PullRequest
0 голосов
/ 21 апреля 2010

Я включил этот заголовок в один из своих: http://codepad.org/lgJ6KM6b
Когда я скомпилировал, я начал получать такие ошибки:

CMakeFiles/bin.dir/SoundProjection.cc.o: In function `Gnuplot::reset_plot()':
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/include/g++-v4/new:105: multiple definition of `Gnuplot::reset_plot()'
CMakeFiles/bin.dir/main.cc.o:project/gnuplot-cpp/gnuplot_i.hpp:962: first defined here
CMakeFiles/bin.dir/SoundProjection.cc.o: In function `Gnuplot::set_smooth(std::basic_string, std::allocator > const&)':
project/gnuplot-cpp/gnuplot_i.hpp:1041: multiple definition of `Gnuplot::set_smooth(std::basic_string, std::allocator > const&)'
CMakeFiles/bin.dir/main.cc.o:project/gnuplot-cpp/gnuplot_i.hpp:1041: first defined here
CMakeFiles/bin.dir/SoundProjection.cc.o:/usr/include/eigen2/Eigen/src/Core/arch/SSE/PacketMath.h:41: multiple definition of `Gnuplot::m_sGNUPlotFileName'

Я знаю, что в этом беспорядке трудно увидеть, но посмотрите, где происходят переопределения. Они размещаются в таких файлах, как /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/include/g++-v4/new:105. Как новый оператор получает информацию о заголовке gnuplot? Я даже не могу отредактировать этот файл. Как это вообще возможно? Я даже не уверен, как начать отлаживать это. Я надеюсь, что предоставил достаточно информации. Я не смог воспроизвести это в небольшом проекте. Я в основном просто ищу советы о том, как выяснить, почему это происходит, и как это отследить.

Спасибо.

Ответы [ 3 ]

3 голосов
/ 21 апреля 2010

Вы явно нарушаете "правило одного определения". У вас есть много определений в вашем заголовочном файле. Некоторые из них являются классами или шаблонами классов (что хорошо), некоторые из них являются встроенными функциями или шаблонами функций (что также хорошо), а некоторые из них являются «обычными» функциями и статическими членами не-шаблонов (что не хорошо ).

class foo;       // declaration of foo
class foo {      // definition of foo
   static int x; // declaration of foo::x
};

int foo::x;      // definition of foo::x

void bar();      // declaration
void bar() {}    // definition

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

1 голос
/ 21 апреля 2010

Похоже, вы включили конфликтующие заголовки. Попробуйте проверить ваши пути включения. Они обычно определяются в директиве -I (по крайней мере, в gcc) или в переменной окружения.

0 голосов
/ 21 апреля 2010

Чтение ошибок компилятора обычно помогает. Вы должны научиться понимать, что говорит вам компилятор. Тот факт, что он жалуется на переопределение символа, говорит о том, что вы нарушаете Правило Единого Определения. Тогда он даже скажет вам, что это за символы:

class GnuPlot {
//...
   GnuPlot& reset_plot(); // <-- declaration
//...
};
//...
Gnuplot& Gnuplot::reset_plot() { // <-- Definition
    nplots = 0;
    return *this;
}

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

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

Немного более проблематичными являются статические члены, которые должны быть объявлены внутри класса и определены (только один раз) в модуле перевода. Для этого вы можете либо создать файл .cpp, чтобы определить эти переменные (и любые функции / методы, которые вам не нужны, встроенные в заголовок).

...