Форум программистов, компьютерный форум CyberForum.ru

Глобальная переменная определена в хидере. Компилятор ругается на то, что переменная переопределена несколько раз - C++

Восстановить пароль Регистрация
 
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
05.04.2014, 21:53     Глобальная переменная определена в хидере. Компилятор ругается на то, что переменная переопределена несколько раз #1
Исходники:

C++
1
2
3
4
5
6
/* main.cpp */
#include "hider.h"
int main(void)
{
 return 0;
}
C++
1
2
3
/* foo.cpp */
#include "hider.h"
void bar(void){}
C++
1
2
3
4
5
6
7
//hider.h
#ifndef _HIDER_H
#define _HIDER_H
 
int k;
 
#endif
Команда и результат, компилятор g++
Bash
1
2
3
4
g++ -o main.exe main.cpp foo.cpp
foo.o:foo.cpp:(.bss+0x0): multiple definition of `k'
main.o:main.cpp:(.bss+0x0): first defined here
collect2: ld returned 1 exit status
(При раздельной компиляции то же самое.)

Странно, мне всю жизнь казалось, что
C++
1
2
3
4
#ifndef _HIDER_H
#define _HIDER_H
//код
#endif
Решает эту проблему. ЧЯДНТ? Спасибо, кто откликнется.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.04.2014, 21:53     Глобальная переменная определена в хидере. Компилятор ругается на то, что переменная переопределена несколько раз
Посмотрите здесь:

C++ Глобальная переменная
C++ Глобальная переменная
Глобальная переменная C++
C++ Динамический массив как глобальная переменная
C++ Как объявить переменную глобально?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
05.04.2014, 22:07     Глобальная переменная определена в хидере. Компилятор ругается на то, что переменная переопределена несколько раз #2
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от kravam Посмотреть сообщение
мне всю жизнь казалось, что...Решает эту проблему.
Для одного файла.
В хедере:
C++
1
extern int k; // просто объявление (без определения)
В каком-либо .cpp сделать определение (выделить память).
rrrFer
Заблокирован
05.04.2014, 22:07     Глобальная переменная определена в хидере. Компилятор ругается на то, что переменная переопределена несколько раз #3
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Ну а как ты хотел?
.cpp файл - это единица компиляции. Ты говоришь ему включить заголовочный файл, он слепо и не глядя ни на что его включает. В каждой единице компиляции своя глобальная переменная. Для каждой единице компиляции создается свой объектный файл. Все объектные файлы передаются линкеру и вот тут он замечает, что он не может слепить объектные файлы в кучу потому, что имена глобальных переменных в них пересекаются (он же не знает что ты от всего этого хочешь...).

Посмотри в сторону ключевого слова extern
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
06.04.2014, 02:02  [ТС]     Глобальная переменная определена в хидере. Компилятор ругается на то, что переменная переопределена несколько раз #4
Остался маленький вопрос. Вот это для чего?
C++
1
2
3
4
#ifndef _HIDER_H
#define _HIDER_H
//код
#endif
Обычно я (надеюсь, не только), работая с одним файлом, пишу так:

C++
1
2
3
4
5
6
/* main.cpp */
#include "hider.h"
int main(void)
{
 return 0;
}
Всё. И он скомпилится и без первой конструкции. Зачем же она?

Добавлено через 9 минут
А понял. Это для таких случаев:

C++
1
2
3
4
5
6
7
/* main.cpp */
#include "hider.h"
#include "hider_main.h"
int main(void)
{
 return 0;
}

C++
1
2
3
4
5
//hider.h
#ifndef _HIDER_H
#define _HIDER_H
int k;
#endif
C++
1
2
3
4
5
//hider_main.h
#ifndef _HIDER_MAIN_H
#define _HIDER_MAIN_H
#include "hider.h"
#endif
Bash
1
g++ -o main.exe main.cpp
rrrFer
Заблокирован
06.04.2014, 04:45     Глобальная переменная определена в хидере. Компилятор ругается на то, что переменная переопределена несколько раз #5
Цитата Сообщение от kravam Посмотреть сообщение
Остался маленький вопрос. Вот это для чего?
Для того, чтобы твоя глобальная переменная не оказалась включена в один объектный файл несколько раз.

в 1.h описана глобальная переменная
2.h включает 1.h
3.h включает 1.h и 2.h

Если в 1.h нет "этого" - то глобальная переменная будет описана дважды, о чем ты получишь сообщение.

В противном случае (если "это" описано), то 3.h при обработке очередного include обнаруживает, что _HIDER_H уже определен и пропускает то, что внутри #ifndef _HIDER_H.
Yandex
Объявления
06.04.2014, 04:45     Глобальная переменная определена в хидере. Компилятор ругается на то, что переменная переопределена несколько раз
Ответ Создать тему
Опции темы

Текущее время: 00:58. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru