LINUX.ORG.RU

multiple definition


0

0

Здравствуйте! Я тут с траблом столкнулся и никак не найти хорошего решения. Есть файл base.h в котором хранятся констатнты const char* name = «lalala »; const int i=1; итд сделал base.cpp в котором #include «base.h»

И есть куча других файлов в которые эти могут быть включены . Те понятно что если я включу base.h, то компилятор будет недоволен. И ведь так и есть. Он выводит мне сообщение

/tmp/ccktgfzP.o:(.data+0xc): multiple definition of `pass1'                                                                                             
/tmp/cc89OBJZ.o:(.data+0xc): first defined here                                                                                                         
/tmp/ccktgfzP.o:(.data+0x8): multiple definition of `user1'                                                                                             
/tmp/cc89OBJZ.o:(.data+0x8): first defined here                                                                                                         
/tmp/ccktgfzP.o:(.data+0x4): multiple definition of `server1'
/tmp/cc89OBJZ.o:(.data+0x4): first defined here
/tmp/ccktgfzP.o:(.data+0x0): multiple definition of `db1'
/tmp/cc89OBJZ.o:(.data+0x0): first defined here
/tmp/ccvRK6bo.o:(.data+0x0): multiple definition of `db1'
Вот как с этим вообще бороться? Не хотелось бы в каждом файле определять новые константы или пространство имен лишнее создавать. Ведь можно же как-то сказать компилятору что этот файл один для всего проекта и нечего лишний раз орать при встрече таких то определений.


Вообще то переменные (даже константы) определять в заголовочных файлах не есть гут.

Как вариант использовать #define

kayrick
()
Ответ на: комментарий от kayrick

Или завести для них отдельный файл *.c и в заголовочных объявлять как extern

kayrick
()

Другой подобный вариант использования кстати, когда вы должны инициализировать те несколько
неизбежных глобальных переменных в большой программе. Проблема заключается в синхронизации
объявлений переменных (в заголовочном файле) с их определениями (в файле .c), где реально
выделяется память и переменные инициализируются. Вот образец заголовочного файла:
        #ifdef ALLOC
        #define I(x) x
        #define EXPORTED /* пусто */
        #else
        #define I(x) /* пусто */
        #define EXPORTED extern
        #endif

        EXPORTED int glob_x[10] I( ={1, 2, 3, 4} );
        EXPORTED some_object glob_y I( ("конструктор", "аргументы") );
В определенном месте своей программы (я обычно делаю это в файле с именем globals.cpp) вы
помещаете следующие строки:
        #define ALLOC
        #include "globals.h"
Далее везде вы просто включаете этот файл без предварительной директивы #define ALLOC. Когда
вы компилируете globals.cpp, директива #define ALLOC вызывает следующую подстановку:
        /* пусто */ int glob_x[10] ={1, 2, 3, 4} ;
        /* пусто */ some_object glob_y ("конструктор", "аргументы") );
Отсутствие #define ALLOC везде приводит к следующей подстановке:
        extern int glob_x[10] /* пусто */ ;
        extern some_object glob_y /* пусто */ ;

(c) веревка достаточной длинны, чтобы выстрелить себе в ногу

SSZB
()
Ответ на: комментарий от P1XeL

> #ifndef MY_HEADER_H #define MY_HEADER_H

Не, не поможет, эта защита от множественного инклуда хедера в один c/cpp-файл, а если сделать инклуд в разные c/cpp-файлы, то будет ругаться линкер как у автора темы.

SSZB
()

Ну не экспортируй их из каждого translation unit, пиши в хедере static const int i...

mqspi
()
Ответ на: комментарий от kayrick

Ну Страуступ другого менения. Он говорил что константы определять можно и даже нужно в .h файлах. Пишу на с++.

jeep
() автор топика
Ответ на: комментарий от SSZB

Вообще спасибо большое за содержательные ответы!

jeep
() автор топика

У меня обычно в каждом проекте есть global.h/.cpp со всякими общими классами, функциями, а также константами (определены в .cpp, а в .h только их объявления с extern)

mannaz
()

можно по идее определить оидн раз в исходниках, а в хедерах писать extern <...>. И их подключать везде

chicane
()
Ответ на: комментарий от dilmah

> Константы можно static объявить..

В C++ всё локальное лучше поместить в безымянные пространства имён:

namespace
{
    int someconst = 123;
};

Deleted
()

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

Например:

.h:

#ifndef _FOO_

#define _FOO_

extern const char *bar;

#endif

.cpp:

const char *bar = "Hello LOR";

Читайте внимательнее Страуструпа. ж)

SSN
()
Ответ на: комментарий от SSN

константа и указатель на константу - две большие разницы. В приведённом примере можно написать где-нибудь в коде:

bar = "Goodbye LOR";

какая же это константа? Это обычная глобальная переменная.

Legioner ★★★★★
()

extern const char* name = "lalala ";

И один раз где-нибудь, в одном файле определить их, вот и все дела.

Dudraug ★★★★★
()
Ответ на: комментарий от P1XeL

> const char * b = "blabla";

Тут у тебя b не константа, а обычная переменная, которая указывает на строку, которую нельзя менять. Надо так:

const char *const b = "blabla";

zzf
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.