Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сборка цели из нескольких объектных файлов 
:(
    Опции темы
EnergoHokum
Дата 6.12.2007, 09:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 600
Регистрация: 10.11.2006
Где: Россия, Ставропол ь

Репутация: нет
Всего: 6



Такой вопрос: есть, к примеру, файлы first.cpp, first.h, second.cpp, second.h.
Из них собираются объектные файлы соответственно first.o и second.o, которые после слинковываются в одну библиотеку.
В second.h объявлена переменная, которая используется как в first.cpp, так и в second.cpp. Соответственно, second.h включен и в first.cpp, и в second.cpp. При линковке компилятор ругается на то, что в обоих *.o файлах объявление этой переменной дублируется. Правильно ли будет задать ей модификатор static, или есть "более другие" методы решения этой проблемы?
PM MAIL ICQ   Вверх
MAKCim
Дата 6.12.2007, 10:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



EnergoHokum, 
в second.h
переменная должна быть объявлена с модификатором extern
а определена в одном из .cpp-файлов
Цитата(EnergoHokum @  6.12.2007,  09:49 Найти цитируемый пост)
Правильно ли будет задать ей модификатор static, или есть "более другие" методы решения этой проблемы? 

неправильно, если переменная должна быть глобальной для всех модулей
если ее определить как static, то в каждом модуле будет свой локальный экземпляр переменной
Код

// second.h
...
extern int variable;
...

Код

// variable.cpp

int variable = 1; // определение

Код

// first.cpp

#include "first.h"
#include "second.h"
...

Код

// second.cpp

#include "second.h"
...


Это сообщение отредактировал(а) MAKCim - 6.12.2007, 10:12


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
EnergoHokum
Дата 6.12.2007, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 600
Регистрация: 10.11.2006
Где: Россия, Ставропол ь

Репутация: нет
Всего: 6



Хм, когда переопределил с extern, пошла ругань вида: ...undefined reference to.... Эту переменную нужно инициализировать в соответствующем *.cpp, или всё равно где?

Это сообщение отредактировал(а) EnergoHokum - 6.12.2007, 10:15
PM MAIL ICQ   Вверх
MAKCim
Дата 6.12.2007, 10:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



EnergoHokum, 
я же пример написал специально
Цитата(EnergoHokum @  6.12.2007,  10:15 Найти цитируемый пост)
Эту переменную нужно инициализировать в соответствующем *.cpp, или всё равно где?

все равно, главное должно быть где-то определение (но не в .h-файле естественно)


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
EnergoHokum
Дата 6.12.2007, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 600
Регистрация: 10.11.2006
Где: Россия, Ставропол ь

Репутация: нет
Всего: 6



В общем, упрощённо ситуация такая:
Код

//main.cpp
#include <iostream>
#include "./second.h"
#include "./main.h"

int first(void)
{
    std::cout<<"imain+500="<<(imain+=500)<<std::endl;
    std::cout<<"main.cpp -> first()"<<std::endl;
    return 0;
}

int main(int argc,char** argv)
{
    second();
    return 0;
}

Код

//main.h
#ifndef MAIN_H_20071205_1945
#define MAIN_H_20071205_1945

int imain;
char* chmain;

int first(void);

#endif

Код

//second.cpp
#include <string.h>
#include <iostream>
#include "./second.h"
#include "./main.h"

int second(void)
{
    imain=555;
    std::cout<<"imain="<<imain<<std::endl;
    std::cout<<"second.cpp -> second(), \
call main.cpp -> first()\n"<<std::endl;
    first();
    chmain=new char[strlen("test string of second")+1];
    memcpy(chmain,"test string of second",strlen("test string of second")+1);
    std::cout<<"chmain is "<<chmain<<std::endl;
    return 0;
}

Код

//second.h
#ifndef SECOND_H_20071205_1950
#define SECOND_H_20071205_1950

int second(void);

#endif

Код

REMOVE = rm -f
EXEC = a
FIRST = main
SECOND = second
SOURCE = $(FIRST).cpp $(SECOND).cpp
HEADER = $(FIRST).h $(SECOND).h
OBJECT = $(FIRST).o $(SECOND).o

$(EXEC): $(OBJECT)
    g++ -o $(EXEC) $(OBJECT)

$(OBJECT): $(SOURCE) $(HEADER)
    g++ -c $(SOURCE)

clean:
    $(REMOVE) $(wildcard *.o)
    $(REMOVE) $(wildcard *.exe)
    $(REMOVE) $(EXEC)

all:
    $(MAKE) $(EXEC)

ALL: clean all


Действительно, при объявлении переменных со static для каждого .o-файла они получаются свои, но и с extern тоже ничего хорошего не выходит.
PM MAIL ICQ   Вверх
t_gran
Дата 6.12.2007, 10:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 621
Регистрация: 13.11.2007
Где: г.Усть-Илимск

Репутация: 1
Всего: 37



Предлагаю так:

Код

// second.h

#ifndef __SECOND_H__
#define __SECOND_H__

int variable;

#endif




--------------------
Я знаю, что ничего не знаю© Сократ
user posted image
PM MAIL WWW   Вверх
MAKCim
Дата 6.12.2007, 10:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Код

//main.h
#ifndef MAIN_H_20071205_1945
#define MAIN_H_20071205_1945

extern int imain;
extern char* chmain;

extern int first(void);

#endif

Код

// global.cpp

int imain;
char * chmain;

Код

REMOVE = rm -f
EXEC = a
FIRST = main
SECOND = second
SOURCE = $(FIRST).cpp $(SECOND).cpp global.cpp
HEADER = $(FIRST).h $(SECOND).h
OBJECT = $(FIRST).o $(SECOND).o global.o
$(EXEC): $(OBJECT)
    g++ -o $(EXEC) $(OBJECT)
$(OBJECT): $(SOURCE) $(HEADER)
    g++ -c $(SOURCE)
clean:
    $(REMOVE) $(wildcard *.o)
    $(REMOVE) $(wildcard *.exe)
    $(REMOVE) $(EXEC)
all:
    $(MAKE) $(EXEC)
ALL: clean all



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
EnergoHokum
Дата 6.12.2007, 10:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 600
Регистрация: 10.11.2006
Где: Россия, Ставропол ь

Репутация: нет
Всего: 6



Мне нужно, чтобы переменные оставались там, где они лежат сейчас, по контексту они так привязаны. Можно (наверное) вообще сгрести их все в один .h-файл, но это не решение. Это здесь два объектника, а в проекте их больше. Перетряхивать всю структуру проекта? Это практически невозможно.

Это сообщение отредактировал(а) EnergoHokum - 6.12.2007, 10:53
PM MAIL ICQ   Вверх
MAKCim
Дата 6.12.2007, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(EnergoHokum @  6.12.2007,  10:50 Найти цитируемый пост)
Мне нужно, чтобы переменные оставались там, ult они лежат сейчас, по контексту они так привязаны. Можно (наверное) вообще сгрести их все в один .h-файл, но это не решение. 

ну что значит привязаны?
разве сейчас что-то изменилось?
абсолютно ничего, просто определение переменных я вынес в отдельный .cpp-файл
чтобы не было нарушения правила одного определения при подключении .h-файла в разные .cpp-файлы
по-другому здесь не сделаешь
в .h-файле не должно быть не static-определений

Это сообщение отредактировал(а) MAKCim - 6.12.2007, 10:56


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Alek86
Дата 6.12.2007, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



MAKCim, а зачем 
Код
extern int first(void);
?

и оффтопный вопрос. где-то слышал, что static (не в функциях) делать не рекомендуется. почему, не подскажешь?


--------------------
user posted image    user posted image
PM MAIL   Вверх
MAKCim
Дата 6.12.2007, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(Alek86 @  6.12.2007,  10:58 Найти цитируемый пост)
а зачем 

имхо, так наглядней
Цитата(Alek86 @  6.12.2007,  10:58 Найти цитируемый пост)
и оффтопный вопрос. где-то слышал, что static (не в функциях) делать не рекомендуется. почему, не подскажешь? 

если речь о С++, то там есть анонимные пространства имен, которые заменяют static


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
EnergoHokum
Дата 6.12.2007, 11:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 600
Регистрация: 10.11.2006
Где: Россия, Ставропол ь

Репутация: нет
Всего: 6



Ви будете смеяться, но таки ничего не изменилось! Или это я уже туплю?
Да, действительно, туплю. Но всё равно как-то неизящно выходит. Счас поковыряюсь ещё, может, что и придумается...

Это сообщение отредактировал(а) EnergoHokum - 6.12.2007, 11:08
PM MAIL ICQ   Вверх
MAKCim
Дата 6.12.2007, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(EnergoHokum @  6.12.2007,  11:06 Найти цитируемый пост)
Ви будете смеяться, но таки ничего не изменилось! Или это я уже туплю? 

global.cpp создал?
поместил туда определение символов?
добавил в Makefile global.cpp и global.o


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Alek86
Дата 6.12.2007, 11:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



Цитата(MAKCim @  6.12.2007,  11:05 Найти цитируемый пост)
если речь о С++, то там есть анонимные пространства имен, которые заменяют static

это и есть причина для устранения? жестко....


--------------------
user posted image    user posted image
PM MAIL   Вверх
Random13
Дата 6.12.2007, 11:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 116
Регистрация: 21.11.2007

Репутация: нет
Всего: нет



Цитата(MAKCim @ 6.12.2007,  10:55)
в .h-файле не должно быть не static-определений

А разве статик не должны быть тоже определены в срр файле ?
В h файле только, вроде, объявление идет, а память должна выделятся в срр ?

Как я понимаю, в одном файле h глобальная переменная должна быть объявлена без extern, этот файл должен быть подключен к срр, где ей отводится память, в остальных  h файлах должно стоять extern.
Разве только для static - extern бесполезно делать ее видимость все равно ограничивается файлом.

Это сообщение отредактировал(а) Random13 - 6.12.2007, 11:34
PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0645 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.