Ошибка компиляции нескольких файлов (не пойму, что хочет компилятор.)

Модератор: Модераторы разделов

Аватара пользователя
powerfox
Сообщения: 458

Ошибка компиляции нескольких файлов

Сообщение powerfox »

Разбил программу на несколько исходных файлов с одним заголовочным файлом - не хочет компилироваться:

Код: Выделить всё

[fox@localhost snake]$ g++ *.cpp snake.h `sdl-config --cflags --libs`
/home/fox/tmp/cch5qfyz.o(.bss+0x0): multiple definition of `back'
/home/fox/tmp/cc53elHh.o(.bss+0x0): first defined here
/home/fox/tmp/cch5qfyz.o(.bss+0x4): multiple definition of `image'
/home/fox/tmp/cc53elHh.o(.bss+0x4): first defined here
/home/fox/tmp/cch5qfyz.o(.bss+0x8): multiple definition of `screen'
/home/fox/tmp/cc53elHh.o(.bss+0x8): first defined here
/home/fox/tmp/cch5qfyz.o(.bss+0xc): multiple definition of `xpos'
/home/fox/tmp/cc53elHh.o(.bss+0xc): first defined here
/home/fox/tmp/cch5qfyz.o(.bss+0x10): multiple definition of `ypos'
/home/fox/tmp/cc53elHh.o(.bss+0x10): first defined here
/home/fox/tmp/ccHVDm12.o(.bss+0x0): multiple definition of `back'
/home/fox/tmp/cc53elHh.o(.bss+0x0): first defined here
/home/fox/tmp/ccHVDm12.o(.bss+0x4): multiple definition of `image'
/home/fox/tmp/cc53elHh.o(.bss+0x4): first defined here
/home/fox/tmp/ccHVDm12.o(.bss+0x8): multiple definition of `screen'
/home/fox/tmp/cc53elHh.o(.bss+0x8): first defined here
/home/fox/tmp/ccHVDm12.o(.bss+0xc): multiple definition of `xpos'
/home/fox/tmp/cc53elHh.o(.bss+0xc): first defined here
/home/fox/tmp/ccHVDm12.o(.bss+0x10): multiple definition of `ypos'
/home/fox/tmp/cc53elHh.o(.bss+0x10): first defined here
collect2: ld returned 1 exit status
[fox@localhost snake]$


snake.h:

Код: Выделить всё

#ifndef SNAKE_HEADER
#define SNAKE_HEADER
#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>
SDL_Surface *back=SDL_LoadBMP("/docs/programming/Sdl/progs/less2/bg.bmp");
SDL_Surface *image=SDL_LoadBMP("/docs/programming/Sdl/progs/less2/image.bmp");
SDL_Surface *screen=SDL_SetVideoMode(640,480,24,SDL_HWSURFACE|SDL_DOUBLEBUF);
int xpos=0, ypos=0;
void DrawIMG(SDL_Surface *img, int x, int y);
void DrawIMG(SDL_Surface *img, int x, int y, int w, int h, int sx, int sy);
void DrawBG(void);
void DrawScene(void);
void initsystem();
void driver();
#endif //SNAKE_HEAER

Вся программа в прикреплённом архиве
Спасибо сказали:
Аватара пользователя
elide
Бывший модератор
Сообщения: 2421
Статус: Übermensch
ОС: лялих

Re: Ошибка компиляции нескольких файлов

Сообщение elide »

а нахрена ты g++ хэдер скармливаешь?
слава роботам!
Спасибо сказали:
Аватара пользователя
powerfox
Сообщения: 458

Re: Ошибка компиляции нескольких файлов

Сообщение powerfox »

elide писал(а):
06.11.2005 03:26
а нахрена ты g++ хэдер скармливаешь?

Не подумал... :(
Самое интересное, что g++-3.3.2 выдавал сообщение о хэдере, а 3.4.1 - нет. Если не компайлить хэдер - ошибка та же, 3.4.1 автоматически пропускает ;)
Спасибо сказали:
Аватара пользователя
nercus
Сообщения: 150

Re: Ошибка компиляции нескольких файлов

Сообщение nercus »

все переменные в хедере надо задекларировать с extern
и в _одном_ из сишников объявить их (без extern).

поскольку хедер включен в нескольких сишниках, то в случае _без_ extern символы xpos, ypos etc. присутствуют в нескольких объектниках, что несколько обескураживает линковщика, о чем он и сообщает.

PS: вот так вот делать не кошерно:
SDL_Surface *back=SDL_LoadBMP("/docs/programming/Sdl/progs/less2/bg.bmp");
SDL_Surface *image=SDL_LoadBMP("/docs/programming/Sdl/progs/less2/image.bmp");
SDL_Surface *screen=SDL_SetVideoMode(640,480,24,SDL_HWSURFACE|SDL_DOUBLEBUF);

инициализацию наверно в initsystem(), а объявлять "= NULL".... имхо ;)
2.6.14-gentoo-r5
kde-3.5.0 | openbox-3.2
Deep Purple | Rob Zombie | Led Zeppelin | ДДТ
Спасибо сказали:
Аватара пользователя
powerfox
Сообщения: 458

Re: Ошибка компиляции нескольких файлов

Сообщение powerfox »

Спасибо!
Правда, я back, image, screen засунул в initsystem() (и объявление, и инициализацию), а xpos и ypos в driver() - оказалось, они нигде больше не нужны.
Не совсем понял про "=NULL".
Спасибо сказали:
Аватара пользователя
nercus
Сообщения: 150

Re: Ошибка компиляции нескольких файлов

Сообщение nercus »

про NULL - имел в виду, что при объявлении инициализировать глобальные переменные возвращаемым значением некой функции не есть гут. в таких случаях лучше делать некую функцию инициализации (к примеру initsystem) и в ней производить фактическую инициализацию, а при объявлении инициализировать некой special-case константой.
2.6.14-gentoo-r5
kde-3.5.0 | openbox-3.2
Deep Purple | Rob Zombie | Led Zeppelin | ДДТ
Спасибо сказали:
Аватара пользователя
powerfox
Сообщения: 458

Re: Ошибка компиляции нескольких файлов

Сообщение powerfox »

elide писал(а):
06.11.2005 03:26
а нахрена ты g++ хэдер скармливаешь?

Учитывая, что вы не правы - я бы на вашем месте не употреблял оборот "а нахрена".
g++(начиная с какой-то версии, у меня 3.4.1) компилирует заголовочные файлы, создавая бинарный файл *.h.gch для ускорения последующих компиляций. Если есть заголовочный файл name.h и name.h.gch, name.h игнорируется и используется name.h.gch. В деталях могу и ошибаться, но суть верна. Если хотите поподробнее "в google"! ;)

nercus писал(а):
06.11.2005 19:35
про NULL - имел в виду, что при объявлении инициализировать глобальные переменные возвращаемым значением некой функции не есть гут. в таких случаях лучше делать некую функцию инициализации (к примеру initsystem) и в ней производить фактическую инициализацию, а при объявлении инициализировать некой special-case константой.

Так нельзя, инициализировать в заголовочном файле можно только константы(а не любые переменные константой).
Спасибо сказали:
Аватара пользователя
nercus
Сообщения: 150

Re: Ошибка компиляции нескольких файлов

Сообщение nercus »

powerfox писал(а):
11.11.2005 21:08
Так нельзя, инициализировать в заголовочном файле можно только константы(а не любые переменные константой).

вА-первых, я про заголовочные файлы не говорил. я сказал "при _объявлении_" (то что без extern, дабы было понятнее, то, что находится в сишнике).

вА-втАрых. если быть дотошно точным, то в заголовочном файле можно делать абсолютно все то же, что и в обыкновенном сишнике.

Код: Выделить всё

$ cat x.h
#include <stdio.h>
int x = 5; int main() { printf("%d\n",x); return 0;}

$ cat y.c
#include "x.h"

$ gcc y.c -o y
$ ./y
5

другой вопрос, что делать так не надо;)


теперь о тоне. хоть это было адресованно и не мне, но все равно как-то неприятно.
powerfox писал(а):
06.11.2005 12:56
elide писал(а):
06.11.2005 03:26

а нахрена ты g++ хэдер скармливаешь?

Не подумал... sad.gif
Самое интересное, что g++-3.3.2 выдавал сообщение о хэдере, а 3.4.1 - нет. Если не компайлить хэдер - ошибка та же, 3.4.1 автоматически пропускает

и после этого, через 5 дней:
powerfox писал(а):
11.11.2005 21:08
Учитывая, что вы пишите "ХРЕНЬ" - я бы на вашем месте не употреблял оборот "а нахрена".

то есть, сначала вы согласились, что хедер компилять не надо. потом видимо что-то где-то почитали (молодцы). и решили выпендриться. но говорить человеку, что он пишет "ХРЕНЬ" - имхо не лучший способ обратить на себя внимание...
2.6.14-gentoo-r5
kde-3.5.0 | openbox-3.2
Deep Purple | Rob Zombie | Led Zeppelin | ДДТ
Спасибо сказали:
Аватара пользователя
powerfox
Сообщения: 458

Re: Ошибка компиляции нескольких файлов

Сообщение powerfox »

[quote name='nercus' date='Nov 11 2005, в 22:29' post='134923']
[quote name='powerfox' post='134885' date='Nov 11 2005, в 21:08']Так нельзя, инициализировать в заголовочном файле можно только константы(а не любые переменные константой).[quote]


вА-втАрых. если быть дотошно точным, то в заголовочном файле можно делать абсолютно все то же, что и в обыкновенном сишнике.

[quote]
Только если заголовочный файл не включается в несколько с/с++ файлов. Попробуйте добывить второй исходный файл с тем включением и скомпелировать - не запашет.

[quote]
теперь о тоне. хоть это было адресованно и не мне, но все равно как-то неприятно.
[quote]

Грубовато вышло, извиняюсь. Но всё стояло в ковычках - было взято из сообщения elide. Не спорю, что, возможно, elide классный программер, но все его сообщения на чужие посты написаны в грубом тоне, цитатами я хотел ЭТО показать.
Ни в коем случае ни выпендриваюсь, просто хотел показать elide, что надо думать, что пишешь(если пишешь так самоуверенно).
Спасибо сказали:
Аватара пользователя
nercus
Сообщения: 150

Re: Ошибка компиляции нескольких файлов

Сообщение nercus »

powerfox писал(а):
12.11.2005 19:25
Только если заголовочный файл не включается в несколько с/с++ файлов. Попробуйте добывить второй исходный файл с тем включением и скомпелировать - не запашет.

я всего лишь показал, что можно - в ответ на "нельзя". не нужно - да, факт, но можно;)
кажется, я об этом уже говорил... в ответ на ваш первый пост ;)
nercus писал(а):
06.11.2005 15:59
все переменные в хедере надо задекларировать с extern
и в _одном_ из сишников объявить их (без extern).

поскольку хедер включен в нескольких сишниках, то в случае _без_ extern символы xpos, ypos etc. присутствуют в нескольких объектниках, что несколько обескураживает линковщика, о чем он и сообщает.
2.6.14-gentoo-r5
kde-3.5.0 | openbox-3.2
Deep Purple | Rob Zombie | Led Zeppelin | ДДТ
Спасибо сказали:
Аватара пользователя
powerfox
Сообщения: 458

Re: Ошибка компиляции нескольких файлов

Сообщение powerfox »

Виноват, извините.
Спасибо сказали: