множественное определение в c++

127
30 января 2020, 03:00

Есть такой файл заголовок(header).

#ifndef GLOBAL_H
#define GLOBAL_H
enum { SPRITE, PANEL };
struct global {
        int width;
        int height;
        int programs[ 2 ];
        int color;
        char *root;
};
struct global global;
#endif
extern struct global global;

Такой код без проблем компилируется в си, но в с++ возникают ошибки. Как тут справиться, если мне нужна логика сишной программы? Или как надо делать?

Вот ошибка

/tmp/ccCJF1ju.o:(.bss+0x0): multiple definition of `global'
/tmp/cckmT2vV.o:(.bss+0x0): first defined here
/tmp/ccsDCDPj.o:(.bss+0x0): multiple definition of `global'
/tmp/cckmT2vV.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status
makefile:4: recipe for target 'all' failed
Answer 1

Судя по сообщениям об ошибке, ваш код страдает от проблемы множественного определения вызванного определением объекта с внешним связыванием в заголовочном файле.

  • Во-первых, требования, предъявляемые к таким определениям, одинаковы в С и в С++. Ваш код одинаково ошибочен и в С, и в С++. То, что он у вас "компилировался" в режиме С является не более чем особенностью/странностью/глюком вашего компилятора.

  • Во-вторых, у вас в коде наблюдаются попытки решить эту проблему при помощи т.наз. "include guards" (#ifndef и т.д.). Include guards не имеют никакого отношения к этой проблеме и никак ее не решают.

  • В-третьих, выбор правильного варианта может зависеть от дополнительных требований. Если вам не нужна кросс-компиляция вашего С++ заголовочного файла в С коде, то достаточно определить в заголовочном файле

    #ifndef GLOBAL_H
    #define GLOBAL_H
    struct global {
      ...
    };
    inline global global;
    #endif

    и все. (Использование одного и того же имени для класса и для объекта - не ошибка, но и не самая лучшая идея).

    Если же вам нужна кросс-компиляция с С кодом, то тогда вам придется идти по "классическому" пути: в заголовочном файле лишь объявлять

    extern struct global global;

    а в одном файле реализации определить

    struct global global;

    Однако при этом надо еще не забыть согласовать спецификации линковки (!) при помощи extern "C".

Answer 2

У вас объект структуры

struct global global;

определяется во всех модулях, куда включен данный заголовок. Поэтому и выдается сообщение о множественном определении.

Вам следует вместо этого определения включить объявление объекта структуры в заголовок

#ifndef GLOBAL_H
    //...
    extern struct global global:
#endif

А в каком-нибудь модуле его определить

struct global global;
READ ALSO
Сортировка по глубине в r-tree

Сортировка по глубине в r-tree

Использую r-tree из boost (geometry) для создания графической 2D сцены и возник такой вопрос: как сортировать объекты (box) по глубинеНа данный момент...

126
Вопрос по двунаправленному итератору [закрыт]

Вопрос по двунаправленному итератору [закрыт]

Хотите улучшить этот вопрос? Переформулируйте вопрос, чтобы он соответствовал тематике «Stack Overflow на русском»

150
Компиляция в mingw64 в линукс для windows

Компиляция в mingw64 в линукс для windows

У меня ubuntu и я случайно узнал что в ubuntu есть пакет mingw64 ( а потом и о проекте в сети )Я установил их

139