LINUX.ORG.RU

Masm2cpp: сборщик размещает переменную, инициализация и использование до размещения

 , ,


0

2

Пытаюсь съэмулировать dos 16бит сегменты и dos linker. Линкер мог сегменты собирать в группы (по факту пределах 64к).

Если не понятно -объясню понятнее.

Хотел сделать так чтобы я мог пользоваться переменной (b.cpp), но она за размещение отвечал другой объектный модуль (bb_group.cpp).

Подскажите, почему собирается, но падает и в отладчике я вижу разные адреса для caa и group.aaa?

b.cpp:
#include <iostream>

extern int caa; // я внешняя переменная

struct Initializer {
Initializer()
{
 caa=3; // делаем инициализацию внешней переменной
}
};
static const Initializer i; // во время старта, до main

using namespace std;
int main()
{

    cout << "Hello World " << caa << endl;
    return 0;
}

bb_group.cpp:
struct Group
{
  int aaa; // Сама переменная в структуре
};

Group group; // которая в другом объектном файле

int& caa = group.aaa; // делаем ссылку на переменную в объекте

g++ bb_group.cpp b.cpp -O0 -o b -ggdb

Ну как минимум у тебя типы у переменных разные. Почему линкер не ругается, не знаю, но если заменить тип extern i на int&, то как-то оно заработает.

Тут правда может всплыть проблема с инициализацией, т.к. ссылка extern, то её не выкинут и тогда надо разбираться, кто быстрее проинициализируется, сама ссылка или static Initializer, оно скорее всего специфично для реализации, и чуть что сразу сломается.

Короче в таком виде этот путь приведёт тебя только к проблемам, имхо.

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

А что ссылку надо инициализировать?

int& caa = group.aaa;

Т.к. это extern переменная, то это конкретная ячейка памяти, содержащая адрес group.aaa, и инициализироваться она должна в runtime. А кто проинициализируется первым, Inititalizer или ссылка, насколько я понимаю, стандартом не гарантируется.

Тут нужно подробно копать, я бы рекомендовал от такого подхода отказаться, это error prone в чистом виде.

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

плюсую — ведь для этих как раз целей на сколько я понимаю в новых стандартах есть возможность инлайнить переменные...

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

Линкер не должен собрать программу, в которой внешние ссылки не разрешены на уровне модулей. Статик модификатор не нужен, нужно в отдельный .o собирать инициализацию экстерн переменной и его подключать к тем, что используют b.hpp (куда и следует вынести extern [const] int caa).

mazdai ★★★ ()
Ограничение на отправку комментариев: только для зарегистрированных пользователей