LINUX.ORG.RU

extern namespace C++


0

1

Есть 2 файла. images.h

#include "SDL.h"
namespace Images{
	extern const int max_x_cells;
	extern const int max_y_cells;
	extern const SDL_Surface* green;
	extern const SDL_Surface* water;
	extern const SDL_Surface* road;
	extern const SDL_Surface* stone;
	extern const SDL_Surface* forest;
};

images.cpp

#include "SDL.h"
#include "globals.h"

namespace Images{
	const int max_x_cells = 22; 
	const int max_y_cells = 17; 
	const SDL_Surface* green = SDL_LoadBMP(PATH_TEXTURES "green.bmp");
	const SDL_Surface* water = SDL_LoadBMP(PATH_TEXTURES "water.bmp");
	const SDL_Surface* road = SDL_LoadBMP(PATH_TEXTURES "road.bmp");
	const SDL_Surface* stone = SDL_LoadBMP(PATH_TEXTURES "stone.bmp");
	const SDL_Surface* forest = SDL_LoadBMP(PATH_TEXTURES "forest.bmp");
};

В файле map.cpp прописано #include «images.h»

И используются эти переменные, например max_x_cells = width<Images::max_x_cells?width:Images::max_x_cells;

Линковщик выдает ошибку, что не может соединить с Images::max_x_cells и max_y_cells

Как праувильно использовать namespace в другом файле?

Ответ на: комментарий от AF

Почему тут не нужен extern? Я же не собираюсь переопределять переменную, я хочу использовать переменную с этим именем, объявленную в другом файле

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

Та у тебя весь images.h ненужен (:

Построке const int max_x_cells = 22; компилер понимает, что надо выделить память под переменную.

По строке extern const int max_x_cells; компилер понимает, что память выделена дето еще.

А если написать эти две строки последовательно, то то фигня какая то получается. Вроде и память надо выделить но она вроде уже дето выделена.

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

Так у тебя не 2 фалйа?

Запутал (:

Но подряд extern и определение переменной таки писать не стоит

AF ★★★ ()

.h:

namespace xx{
 extern const int var;
}

1.cpp:

namespace xx{
 const int var=42;
}

2.cpp:

int value=xx::var*2; //=84

А присваивать переменной xx::var ничего нельзя, она же const. Сними const и присваивай.

staseg ★★★★★ ()
Ответ на: комментарий от staseg
g++  -o "CivilGame"  ./core.o ./event.o ./globals.o ./gui.o ./images.o ./main.o ./map.o ./objects.o   -lSDL -lSDL_image -lSDL_ttf
./map.o: In function `Map::loadMap(char const*)':
/home/chubakur/workspace/CivilGame/Debug/../map.cpp:127: undefined reference to `Images::max_x_cells'
/home/chubakur/workspace/CivilGame/Debug/../map.cpp:128: undefined reference to `Images::max_y_cells'
collect2: выполнение ld завершилось с кодом возврата 1

https://github.com/chubakur/CivilGame/blob/master/images.cpp

https://github.com/chubakur/CivilGame/blob/master/images.h

https://github.com/chubakur/CivilGame/blob/master/map.cpp

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

Все просто, так как Images::max_x_cells нигде не объявлен (include ведь нет?) как extern, то по умолчанию он internal linkage - ЛОКАЛЬНЫЙ!

Можно написать (см. стандарт):

extern const int max_x_cells = 22;

и все будет ОК.

io ★★ ()
Ответ на: комментарий от unsigned
         U SDL_LoadBMP_RW
         U SDL_RWFromFile
000000ec t global constructors keyed to Images::green
00000000 t __static_initialization_and_destruction_0(int, int)
00000008 B Images::road
00000000 B Images::green
0000000c B Images::stone
00000004 B Images::water
00000010 B Images::forest
0000007c r Images::max_x_cells
00000080 r Images::max_y_cells

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

Прочитал, что переменные инициализированные со спецификатором const - сначала static. Поэтому зачем нужен extern - понятно. Но почему переменные

const SDL_Surface* green = SDL_LoadBMP(PATH_TEXTURES «green.bmp»);

несмотря на const - extern сразу, и если поставить перед ними extern, то вылезет ошибка компиляции

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

И почему остальные переменные нормально линковались?

Потому что они не константы, они изменяемые указатели на константы.

Begemoth ★★★★★ ()
Последнее исправление: Begemoth (всего исправлений: 1)
Ответ на: комментарий от Chubakur

man nm - экспортируемые символы обознаючаются заглавными буквами во второй колонке.

Почему другие символы экспортировались - видимо, нюансы реализации C++: ты их инициализировал вызовами функций, а не константами, поэтому их пришлось экспортировать, чтобы затем заполнить в стартап-коде.

unsigned ★★★ ()

Тред не читал +#include «images.h» в images.cpp.

Если не понимаешь почему, попробуй вручную линковать gcc или написать пару раз Makefile, должно помочь разобраться как что работает.

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