Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.94/18: Рейтинг темы: голосов - 18, средняя оценка - 4.94
9 / 9 / 0
Регистрация: 10.11.2011
Сообщений: 241
1

undefined reference to `variable`

26.11.2011, 18:49. Показов 3768. Ответов 18
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Вобщем то есть заголовочный файл main.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef _MAIN_H
#define _MAIN_H
 
#include <vector>
#include <windows.h>
 
using std::vector;
 
extern vector<char*>  list;
extern HINSTANCE      hInst;
extern HWND           Static, Threads, ip, Port, Method;
 
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
 
#endif
И файл WndProc.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
#include "main.h"
#include "function.h"
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    char *IP = GetText(ip);
    char *PORT = GetText(Port);
    char *THREADS = GetText(Threads);
    char *METHOD = GetText(Method);
    // функция выглядит так char *GetText(HWND &);
 /* ... */
}
Ну и при компиляции
Код
obj\Release\WndProc.o:WndProc.cpp undefined reference to `ip'
obj\Release\WndProc.o:WndProc.cpp undefined reference to `Port'
//и так по всем переменым
Это появилось после того как решил вынести функцию WndProc в отдельный файл.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.11.2011, 18:49
Ответы с готовыми решениями:

Странная ошибка: [Linker error] undefined reference to `__dyn_tls_init_callback' [Linker error] undefined reference to ld returned 1 exit status
Здравствуйте. Вот недавно начал изучать книгу &quot;С++ для чайников&quot; Стефан Р. Девис 4-е издание. И...

Problem with passing a list variable by a reference
Здравствуйте. Не знал, как нормально сформулировать заглавие на русском! :D В общем такая проблема....

Undefined reference to
Много уже тем создано по даннму вопросу, но решения так и не нашел.. Есть конечно догадки, но как...

undefined reference
Доброго времени суток! Есть следующий код: #include &lt;iostream&gt; using namespace std; enum...

18
Диссидент
Эксперт C
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
26.11.2011, 18:54 2
OrmaJever, В одном из модулей проекта надо внешние переменные объявить без extern, а во всех остальных с extern
1
Заблокирован
26.11.2011, 18:58 3
OrmaJever,

Потому что вы нигде не определили эти переменные. Компилятор видет их объявление, но не знает их определения.

Добавлено через 2 минуты
Цитата Сообщение от Байт Посмотреть сообщение
OrmaJever, В одном из модулей проекта надо внешние переменные объявить без extern, а во всех остальных с extern
Ничего подобного! Можно во всех модулях объявить переменную с extern. Гланое - это определить ее в каком-нибудь модуле, например,

C++
1
extern HWND ip = 0;
0
9 / 9 / 0
Регистрация: 10.11.2011
Сообщений: 241
26.11.2011, 18:59  [ТС] 4
Байт, извините я не понял. Если в main.h обьявлять без extern топотом в многих местах ругается на многократное определение.
0
Заблокирован
26.11.2011, 19:01 5
Цитата Сообщение от OrmaJever Посмотреть сообщение
Байт, извините я не понял. Если в main.h обьявлять без extern топотом в многих местах ругается на многократное определение.
Уважаемый, я же вам все написал. Что же вы обращаетесь к этому Байт, когда тот сам толком не знает?!
0
9 / 9 / 0
Регистрация: 10.11.2011
Сообщений: 241
26.11.2011, 19:02  [ТС] 6
Цитата Сообщение от Сыроежка Посмотреть сообщение
Гланое - это определить ее в каком-нибудь модуле, например,

C++
1
extern HWND ip = 0;
но они определяются только в main.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include "function.h"
#include "main.h"
 
int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nCmdShow)
{
    MSG messages;
    WNDCLASSEX wincl;
    hInst = hThisInstance;
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;
    wincl.style = CS_HREDRAW | CS_VREDRAW;
    wincl.cbSize = sizeof (WNDCLASSEX);
    wincl.hIcon = NULL;
    wincl.hIconSm = LoadIcon (NULL, IDI_HAND);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;
    wincl.cbClsExtra = 0;
    wincl.cbWndExtra = 0;
    wincl.hbrBackground = (HBRUSH)COLOR_MENU;
 
 
    if (!RegisterClassEx (&wincl))
        return 0;
 
    HWND hwnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,szClassName,"aaa",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,400,300,HWND_DESKTOP,NULL,hThisInstance,NULL);
    ip = CreateWindow("EDIT", 0, WS_BORDER | WS_VISIBLE | WS_CHILD, 33,10,120,20, hwnd, 0, hThisInstance, NULL);
    Port = CreateWindow("EDIT", 0, WS_BORDER | WS_VISIBLE | WS_CHILD, 205,10,50,20, hwnd, 0, hThisInstance, NULL);
    Threads = CreateWindow("EDIT", 0, WS_BORDER | WS_BORDER | WS_VISIBLE | WS_CHILD, 72,40,50,22, hwnd, 0, hThisInstance, NULL);
    Method = CreateWindow("COMBOBOX", 0, CBS_DROPDOWNLIST | WS_VISIBLE | WS_CHILD, 185,40,70,80, hwnd, 0, hThisInstance, NULL);
    Static = CreateWindow("STATIC", 0, WS_BORDER | WS_VSCROLL | WS_VISIBLE | WS_CHILD, 10,70,360,180, hwnd, 0, hThisInstance, NULL);
/* ... */
}
и как же быть?
0
Заблокирован
26.11.2011, 19:09 7
Что вы тащите кишку кода?! Как следует из вашего первоначального сообщения, вы объявления этих переменных поместили в заголовочный файл. И у вас теперь, как я понимаю, по крайней мере две единицы трансляции видят эти объявления, так? Ну тогда редактор связей не знает, в какой единице трансляции имеется определение этих переменных. Где определение этих переменных, а где их только использование без определения. Разницу между объявлением объекта и определением объекта понимаете?
0
Диссидент
Эксперт C
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
26.11.2011, 19:12 8
Цитата Сообщение от Сыроежка Посмотреть сообщение
Уважаемый, я же вам все написал. Что же вы обращаетесь к этому Байт, когда тот сам толком не знает?!
Спасибо. Вы очень добры.

Добавлено через 1 минуту
Пожалуй, тем, в которых такая вежливая публика, стоит избегать...
2
9 / 9 / 0
Регистрация: 10.11.2011
Сообщений: 241
26.11.2011, 19:21  [ТС] 9
Цитата Сообщение от Сыроежка Посмотреть сообщение
Что вы тащите кишку кода?! Как следует из вашего первоначального сообщения, вы объявления этих переменных поместили в заголовочный файл. И у вас теперь, как я понимаю, по крайней мере две единицы трансляции видят эти объявления, так?
Ну так, WndProc.cpp компилируется отдельно, main.cpp отдельно.
Цитата Сообщение от Сыроежка Посмотреть сообщение
Ну тогда редактор связей не знает, в какой единице трансляции имеется определение этих переменных. Где определение этих переменных, а где их только использование без определения.
Ну вот я и пытаюсь обьявить, но как сказать что используемая переменая в WndProc.cpp отпределяется в main.cpp?
Цитата Сообщение от Сыроежка Посмотреть сообщение
Разницу между объявлением объекта и определением объекта понимаете?
Можно сказать уже понимаю, но ещё бы разок послушал разницу.

Добавлено через 4 минуты
Опишу ситуацию вот так
main.h
C++
1
TYPE variable; // обьявление
main.cpp

C++
1
2
#include "main.h"
variable = some_function(param) // определение
WndProc.cpp
C++
1
2
#include "main.h"
other_function(variable); // использование
Но main.cpp и WndProc.cpp компилируются отдельно, как связать эту переменую?
0
Заблокирован
26.11.2011, 19:34 10
Цитата Сообщение от OrmaJever Посмотреть сообщение
Ну так, WndProc.cpp компилируется отдельно, main.cpp отдельно.

Ну вот я и пытаюсь обьявить, но как сказать что используемая переменая в WndProc.cpp отпределяется в main.cpp?

Можно сказать уже понимаю, но ещё бы разок послушал разницу.

Добавлено через 4 минуты
Опишу ситуацию вот так
main.h
C++
1
TYPE variable; // обьявление
main.cpp

C++
1
2
#include "main.h"
variable = some_function(param) // определение
WndProc.cpp
C++
1
2
#include "main.h"
other_function(variable); // использование
Но main.cpp и WndProc.cpp компилируются отдельно, как связать эту переменую?
Я вам сейчас подробно все объясню. Дело в том, когда в списке спецификаций стоит слово extern для объекта, но сам объект не инициализируется, то это является объявлением объекта, но не его определением. Ежеди присутствует выражение инициализации, то тогда это является опредеением.

Для примера

C++
1
extern int x;  // Это объявление объекта с именем x
C++
1
extern int x = 0;  // Это определение объекта с именем x
Поэтому когда вы во все модули включаете предложение

C++
1
extern HWND ip;
то во всех модулях вы лишь объявили переменную, сказав, что это есть некоторая внешняя переменная.

Естественно компилятор не знает, а гед же эта переменная определена, в каком модуле.

Давайте рассмотрим другой пример. Во все модули вы включили в глобальное пространство имен предложение

C++
1
HWND ip;
Это уже опредеение переменной. Тогда ситуация возникнет другая. Редактор связей увидет несколько определений одного и того же имени. И также сообщит об ошибке.

Как тогда поступить?

Вы в заголовочном файле оставляете свое объявление

C++
1
extern HWND ip;
Но в файле с main вы дополнительно вставляете строку

C++
1
HWND ip;
или

C++
1
extern HWND  ip = 0;
1
Day
1179 / 989 / 83
Регистрация: 29.10.2009
Сообщений: 1,385
26.11.2011, 20:14 11
OrmaJever, я делаю так.
В Хедере пишу
C
1
2
3
4
5
6
#if defined _E
#define _EX extern
#else
#define _EX
#endif
_EX HWND ip, ....
Теперь в одном из файлов проекта (обычно в главном, но это не обязательно) пишу до всех своих хедеров
C
1
#define _E
До сих пор ни разу не подводило
2
Заблокирован
26.11.2011, 20:55 12
Day,

Проблема в том, что это усложняет код, так как теперь 1) надо помнить, какие манифестные константы надо объявлять перед включением того или иного заголовочного файла; 2) может быть коллизия заголовочных файлов, у которых определен такой же макрос, а потому поведение кода будет непредсказуемым; 3) это усложняет сопровождение кода.
0
Day
1179 / 989 / 83
Регистрация: 29.10.2009
Сообщений: 1,385
26.11.2011, 21:13 13
Цитата Сообщение от Сыроежка Посмотреть сообщение
Day,

1) надо помнить, какие манифестные константы надо объявлять перед включением того или иного заголовочного файла;
Эта константа у меня почти едиственная. Запомнить ее легко. Включаю только в главный файл проекта (там где main) И забываю о ней.
2) может быть коллизия заголовочных файлов, у которых определен такой же макрос, а потому поведение кода будет непредсказуемым;
Помещаю свои хедеры за системными. Свой #define ставлю перед своими хедерами. С моими макросами это в конфликт надеюсь не войдет. Я же сторож коду своему.
3) это усложняет сопровождение кода.
За 20 лет использования этой техники пришлось сопровождать несколько десятков проектов с пересекающимся множеством исходников - и ничего.
4) Я никому не навязываю своего подхода.
2
Заблокирован
26.11.2011, 21:17 14
Цитата Сообщение от Day Посмотреть сообщение
Эта константа у меня почти едиственная. Запомнить ее легко. Включаю только в главный файл проекта (там где main) И забываю о ней. Помещаю свои хедеры за системными. Свой #define ставлю перед своими хедерами. С моими макросами это в конфликт надеюсь не войдет. Я же сторож коду своему.
За 20 лет использования этой техники пришлось сопровождать несколько десятков проектов с пересекающимся множеством исходников - и ничего.
4) Я никому не навязываю своего подхода.
У вас единственная, а у других может быть не единственной. Очевидно, вы не принимали участие, я уж не говорю про крупные проекты, но даже в срединх по объему проектов, где заголовочных файлов бывает порядка 150, не считая стандартных.
0
Day
1179 / 989 / 83
Регистрация: 29.10.2009
Сообщений: 1,385
26.11.2011, 22:42 15
Цитата Сообщение от Сыроежка Посмотреть сообщение
У вас единственная, а у других может быть не единственной. Очевидно, вы не принимали участие, я уж не говорю про крупные проекты, но даже в срединх по объему проектов, где заголовочных файлов бывает порядка 150, не считая стандартных.
Уважаемый! Когда же вы научитесь вести себя прилично и не наскакивать на мало знакомых вам людей.
Я же не спрашиваю, в каких проектах участвовали вы, не подвергаю сомнению вашу квалификацию (во всяком случае на страницах этого форума), ни разу не высказал сомений в ваших умственных способностях.
Мое предложение, прекратить этот дурацкий спор, пока нам не надавали по нашим виртуальным задницам, хотя судя по всему, вам на это наплевать.
На этот пост можете не отвечать.
ЗЫ. Хотя если вам для душевного здоровья необходимо, чтобы последнее слово осталось за вами - пожалуйста!
1
9 / 9 / 0
Регистрация: 10.11.2011
Сообщений: 241
26.11.2011, 23:47  [ТС] 16
Цитата Сообщение от Сыроежка Посмотреть сообщение

Вы в заголовочном файле оставляете свое объявление

C++
1
extern HWND ip;
Но в файле с main вы дополнительно вставляете строку

C++
1
HWND ip;
или

C++
1
extern HWND  ip = 0;
Но зачем я тогда обьявляю их в main.h?

Добавлено через 25 минут
Day, спасибо, вроде бы работает.

Добавлено через 28 минут
Так, а что делать с константами? Их нельзя обьявить extern. Схема такая же.
main.h
C++
1
const  char *variable = "string"; // обьявление
main.cpp
C++
1
2
#include "main.h"
some_function(variable) // использование
WndProc.cpp
C++
1
2
#include "main.h"
other_function(variable); // использование
0
Диссидент
Эксперт C
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
27.11.2011, 00:05 17
Цитата Сообщение от OrmaJever Посмотреть сообщение
Так, а что делать с константами? Их нельзя обьявить extern. Схема такая же.
Ну, простейший выход
C
1
#define variable "string"
Хотя за это меня опять могут дураком назвать
Но, видимо, есть и другие...
1
9 / 9 / 0
Регистрация: 10.11.2011
Сообщений: 241
27.11.2011, 00:31  [ТС] 18
Байт, И правда простейшее рядом!
Вот только у меня вопрос, если есть строка "string" она же не очищается из памяти? Я просто не знаю как передавать параметры функции
C++
1
2
3
4
5
funct("string");
// или
char *str = "string";
funct(str);
delete str;
Надеюсь поняли о чём я)
0
Заблокирован
27.11.2011, 06:57 19
Цитата Сообщение от OrmaJever Посмотреть сообщение
Но зачем я тогда обьявляю их в main.h?

Добавлено через 25 минут
Day, спасибо, вроде бы работает.

Добавлено через 28 минут
Так, а что делать с константами? Их нельзя обьявить extern. Схема такая же.
main.h
C++
1
const  char *variable = "string"; // обьявление
main.cpp
C++
1
2
#include "main.h"
some_function(variable) // использование
WndProc.cpp
C++
1
2
#include "main.h"
other_function(variable); // использование
Когда же вы поймете, что надо за советом обращаться не к дилетантам, а к профессионалам?! Что же вы постоянно наступаете на одни и те же грабли?!

Разъясняю подробно.

Константные объекты имеют внутреннее связывание.. Что это означает? Что вы в заголовочном файле можете объявить константный объект и включить этот заголовочный файл во все модули. Это будут разные объекты!, то есть они не ивступят в конфликт с друг другом, так как редактор связей их не будет видеть! Это только если вы объявите константный объект со спецификатором extern, только тогдат редактор связей увидет константу.

Кроме того, вы объявляете указатель на строковый литерал. Корректно его будет объявить как

C++
1
const char *str = "string";
Хотя С++ и разрешает объявлять не константные указатели, тем не мене он предупреждает, что такая запись, то есть при отсутствии константности объекта, на который указывает указатель, не поощряется, так как в новых версиях стандарта это может быть запрещено.

Я не вижу у вас проблем с передачей этого указателя в функции. У вас есть прототип функции, который должен, как я понимаю, принимать параметр, который является константным указателем ( то есть указателем на константный объект). Какие проблемы?!

Добавлено через 4 минуты
Цитата Сообщение от Day Посмотреть сообщение
Уважаемый! Когда же вы научитесь вести себя прилично и не наскакивать на мало знакомых вам людей.
Я же не спрашиваю, в каких проектах участвовали вы, не подвергаю сомнению вашу квалификацию (во всяком случае на страницах этого форума), ни разу не высказал сомений в ваших умственных способностях.
Мое предложение, прекратить этот дурацкий спор, пока нам не надавали по нашим виртуальным задницам, хотя судя по всему, вам на это наплевать.
На этот пост можете не отвечать.
ЗЫ. Хотя если вам для душевного здоровья необходимо, чтобы последнее слово осталось за вами - пожалуйста!
Вы можете конечно демонстрировать свое возмущение, бить себя в грудь, что вы, якобы, участвовали в крупных проетах, но я вам скажу прямо: в крупных проектах такую самодеятельность с макроопределениями зарубают на корню! Проблема в том, что вы даже не поняли, когда я говорил о коллизии заголовочных файлов! Это тот случай, когда потом ощибку в программе будет очень трудно находить! Профессионалы таких вещей не допускают. Это только любители могут 20 лет использовать такие объявления, так как в рамках их небольших проектов это вполне допустимо.

Извините, но я , как профессионал, обязан дать оценку тому, что вы предлагаете, не зависимо от того, нравится вам это или нет.
0
27.11.2011, 06:57
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.11.2011, 06:57
Помогаю со студенческими работами здесь

Undefined reference to
Есть класс NavyPort. Его заголовок: #ifndef NAVYPORT_H #define NAVYPORT_H class NavyPort { ...

Undefined reference
/tmp/ccQRqGm4.o: In function `PoolAllocator::PoolAllocator(unsigned int, unsigned int)':...

Undefined reference to
Как это разрулить? someclass.h namespace SP { Class SomeClass { SomeClass(){}; ...

undefined reference
Пытаюсь разобраться с Box2D. Выпадает куча ошибок типа undefined reference to...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru