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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Gepar
1177 / 533 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
#1

Линковщик студии суёт нос не туда куда надо - C++

09.12.2012, 23:55. Просмотров 1030. Ответов 12
Метки нет (Все метки)

Хочу разбить код на .h и .cpp файл, но эта, самка собаки, линковщик студии начинает творить непотребства.
Пока весь код в .h файлах всё хорошо. Как есть сейчас:
Colors. h - пара функций для изменения цвета в консоли. Код заключён #ifndef COLORS_H #endif
List.h - класс-список с набором функций описанных прямо в классе List (те неявный инлайн у всего). Код заключён в #ifndef LIST_H #endif + в начале кода есть #include "Colors.h"
Main.cpp - обычный main, в начале есть подключение списка #include "List.h"
Студия линкует всё правильно.

Теперь я добавляю List.cpp файл и выношу туда одну функцию из класса List что описан в List.h и тут же студия мне говорит что она два раза сунула SetColor и не знает какой выбрать:
Ошибка 1 error LNK2005: "void __cdecl SetColor(enum ConsoleColor,enum ConsoleColor)" (?SetColor@@YAXW4ConsoleColor@@0@Z) єцх юяЁхфхыхэ т List.obj
Ошибка 2 error LNK2005: "void __cdecl SetDifColors(int)" (?SetDifColors@@YAXH@Z) єцх юяЁхфхыхэ т List.obj

Как она так умудрилась? Я там помню что есть вариант что если вынести все функции из .h в .cpp файл то якобы всё образумится, но мне это не надо делать, мне не нужно все функции выносить в cpp файл. Any ideas ?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.12.2012, 23:55
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Линковщик студии суёт нос не туда куда надо (C++):

ИИ нехочет ходить куда надо - C++
Доброго времени суток. Возникла проблема с ИИ, который никак не хочет корректно работать. Если кто сможет помочь, заранее благодарю. ...

Запись идет не туда куда надо - Delphi
Хочу записать результат вычеслений a2;b2;c2;d2; в поля в вода с переменными a;b;c;d , результат: после нажатия на кнопку выходит...

Панель инструментов установилась не туда куда надо - Windows XP
Доброго всем времени суток ! Написал на C# панель инструментов для IE, с использованием SpicIE. Запустил bat файл для установки,...

Фишка двигается не туда куда надо. и еще немного - Unity, Unity3D
разрабатываю игру на C#, но вот в чем проблема. Фишка двигалась правильно однако сегодня решил продолжить и уже какой то баг. прилагаю все...

ссылки ведут не туда куда должны - HTML, CSS
Здраствуйте! Взял html шаблон стал менять его. переделал страницы в php страницы и менюшку тоже переделал: <nav> <ul...

MediaView налазит туда, куда не должна - Java
Доброго времени суток. Прошу объяснить, что я сделал не так и как это исправить. Собственно делал по этому уроку:...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Kuzia domovenok
1891 / 1746 / 118
Регистрация: 25.03.2012
Сообщений: 5,925
Записей в блоге: 1
09.12.2012, 23:58 #2
Цитата Сообщение от Gepar Посмотреть сообщение
Ошибка 1 error LNK2005: "void __cdecl SetColor(enum ConsoleColor,enum ConsoleColor)" (?SetColor@@YAXW4ConsoleColor@@0@Z) єцх юяЁхфхыхэ т List.obj
У тебя что? Студия русифицирована? Зря. Очень зря. Знатоком английского, чтоб разбираться в ней быть не надо. А подобные сообщения гуглить и вообще искать информацию о студии на порядок тяжелее!
1
kravam
быдлокодер
1695 / 882 / 45
Регистрация: 04.06.2008
Сообщений: 5,459
10.12.2012, 00:18 #3
Цитата Сообщение от Gepar Посмотреть сообщение
Теперь я добавляю List.cpp файл и выношу туда одну функцию из класса List что описан в List.h
То есть тут перегрузкой не пахнет; но

Я конечно небольшой специалист во всём этом, но я все глаза просмотрел и не увидел подтверждения того, что ты функцию определил один раз, как ты сказал. То, что похоже на прототипы функции, похоже на РАЗНЫЕ прототипы функции.

Короче код нужен.
1
Gepar
1177 / 533 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
10.12.2012, 00:34  [ТС] #4
Kuzia domovenok, а причём тут язык, ты думаешь что в gcc ошибки линковщика будут информативнее? Она же один фиг создаёт временные обжекты которые обзывает по своему (имя функции + какой-то псевдо случайный набор символов), ну а когда у неё потом что-то не сходится то выбрасывает имена этих уже "переработанных" функций в обжектах которые она и не смогла слинковать, gcc делает то же самое и ругается при ошибках линковки похоже. По обрывкам слов можно понять на какие функции она ругается что она два раза включила.

Цитата Сообщение от kravam Посмотреть сообщение
Я конечно небольшой специалист во всём этом, но я все глаза просмотрел и не увидел подтверждения того, что ты функцию определил один раз, как ты сказал.
Содержимое Colors.h (если чем-то поможет). Содержимое остального не буду приводить так как там больно много всего, толку особо не будет, обычный class и обычный мейн, только большой
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#ifndef COLORS_H
#define COLORS_H
 
#include<windows.h>
 
//коды цветов
enum ConsoleColor
{
        Black         = 0,
        Blue          = 1,
        Green         = 2,
        Cyan          = 3,
        Red           = 4,
        Magenta       = 5,
        Brown         = 6,
        LightGray     = 7,
        DarkGray      = 8,
        LightBlue     = 9,
        LightGreen    = 10,
        LightCyan     = 11,
        LightRed      = 12,
        LightMagenta  = 13,
        Yellow        = 14,
        White         = 15
};
 
//возможность установки цвета зная заранее его код
void SetColor(ConsoleColor text, ConsoleColor background = White)
{
    static HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hStdOut, (WORD)((background << 4) | text));
}
 
//доп. возможность установкци цвета. Её отличие в том что функция
//выбирает цвета максимально отличающиеся для номеров что рядом (в отличии от распред. цветов в табличке)
void SetDifColors(int nColor)
{
    ConsoleColor color;
    switch(nColor)
    {
    case 0:
        color = Black;
    case 1:
        color = Red;
        break;
    case 2:
        color = Green;
        break;
    case 3:
        color = Blue;
        break;
    case 4:
        color = Yellow;
        break;
    case 5:
        color = LightGray;
        break;
    case 6:
        color = Black;
        break;
    case 7:
        color = Cyan;
        break;
    case 8:
        color = LightRed;
        break;
    case 9:
        color = LightCyan;
        break;
    case 10:
        color = Brown;
        break;
    case 11:
        color = LightGreen;
        break;
    case 12:
        color = LightBlue;
        break;
    case 13:
        color = DarkGray;
        break;
    case 14:
        color = Magenta;
        break;
    case 15:
        color = White;
        break;
    default:
        color = Black;
        break;
    }
    SetColor(color);
}
#endif
Меня больше удивляет почему она начинает два раза в list их включать. Это получается что у меня при выносе кода из list.h в list.cpp часть кода использующего colors.h находится в list.h, а часть в list.cpp после чего линковщик суёт нос не туда куда надо и подсовывает в list.obj определение colors.h для list.h, а потом засовывает определение colors.h для list.cpp. Другого объяснения я не нахожу. Вопрос в том КАКОГО ФИГА сунуть colors.h в list.cpp когда я не прошу этого (в list.cpp есть лишь include list.h), что за медвежья услуга

Добавлено через 4 минуты
Сделал глупое предположение что static элемент в colors.h сбивал линковщик, но нет, если убрать static у HANDLE hStdOut то ничего не поменяется
0
go
Эксперт C++
3586 / 1366 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
10.12.2012, 00:34 #5
Gepar, .h только прототип.
0
Kuzia domovenok
1891 / 1746 / 118
Регистрация: 25.03.2012
Сообщений: 5,925
Записей в блоге: 1
10.12.2012, 00:37 #6
Цитата Сообщение от Gepar Посмотреть сообщение
Меня больше удивляет почему она начинает два раза в list их включать. Это получается что у меня при выносе кода из list.h в list.cpp часть кода использующего colors.h находится в list.h, а часть в list.cpp после чего линковщик суёт нос не туда куда надо и подсовывает в list.obj определение colors.h для list.h, а потом засовывает определение colors.h для list.cpp. Другого объяснения я не нахожу. Вопрос в том КАКОГО ФИГА сунуть colors.h в list.cpp когда я не прошу этого (в list.cpp есть лишь include list.h), что за медвежья услуга
она включает всё это в каждый файл, где прописан этот инклуд. Если у тебя хотя бы два файла, в которых есть #include "colors.h", будет ошибка.

оставь лишь это
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
#ifndef COLORS_H
#define COLORS_H
//коды цветов
enum ConsoleColor
{
        Black         = 0,
        Blue          = 1,
        Green         = 2,
        Cyan          = 3,
        Red           = 4,
        Magenta       = 5,
        Brown         = 6,
        LightGray     = 7,
        DarkGray      = 8,
        LightBlue     = 9,
        LightGreen    = 10,
        LightCyan     = 11,
        LightRed      = 12,
        LightMagenta  = 13,
        Yellow        = 14,
        White         = 15
};
//возможность установки цвета зная заранее его код
void SetColor(ConsoleColor, ConsoleColor = White);
//доп. возможность установкци цвета. Её отличие в том что функция
//выбирает цвета максимально отличающиеся для номеров что рядом (в отличии от распред. цветов в табличке)
void SetDifColors(int nColor);
#endif
А реализацию функций вынеси в СРР файл. Сolors.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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
 #include<windows.h>
#include "Colors.h"
//возможность установки цвета зная заранее его код
void SetColor(ConsoleColor text, ConsoleColor background = White)
{
    static HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hStdOut, (WORD)((background << 4) | text));
}
 
//доп. возможность установкци цвета. Её отличие в том что функция
//выбирает цвета максимально отличающиеся для номеров что рядом (в отличии от распред. цветов в табличке)
void SetDifColors(int nColor)
{
    ConsoleColor color;
    switch(nColor)
    {
    case 0:
        color = Black;
    case 1:
        color = Red;
        break;
    case 2:
        color = Green;
        break;
    case 3:
        color = Blue;
        break;
    case 4:
        color = Yellow;
        break;
    case 5:
        color = LightGray;
        break;
    case 6:
        color = Black;
        break;
    case 7:
        color = Cyan;
        break;
    case 8:
        color = LightRed;
        break;
    case 9:
        color = LightCyan;
        break;
    case 10:
        color = Brown;
        break;
    case 11:
        color = LightGreen;
        break;
    case 12:
        color = LightBlue;
        break;
    case 13:
        color = DarkGray;
        break;
    case 14:
        color = Magenta;
        break;
    case 15:
        color = White;
        break;
    default:
        color = Black;
        break;
    }
    SetColor(color);
}
- ошибка исчезнет
1
kravam
быдлокодер
1695 / 882 / 45
Регистрация: 04.06.2008
Сообщений: 5,459
10.12.2012, 00:41 #7
Ничё не понимаю... А чё, так нельзя упростить код? Разве это упрощение повлияет сколько-нибудь на обсуждаемый вопрос?

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
#ifndef COLORS_H
#define COLORS_H
 
#include<windows.h>
 
//коды цветов
enum ConsoleColor
{
        Black         = 0,
};
 
//возможность установки цвета зная заранее его код
void SetColor(ConsoleColor text,ConsoleColor background = White)
{
    static HANDLE hStdOut;
    SetConsoleTextAttribute(hStdOut, (WORD) 1);
}
 
//доп. возможность установкци цвета. Её отличие в том что функция
//выбирает цвета максимально отличающиеся для номеров что рядом (в отличии от распред. цветов в табличке)
void SetDifColors(int nColor)
{
    ConsoleColor color;
    SetColor(color);
}
#endif
Прикинь, если бы ты весь код дал (а многие так и делают), я бы САМ весь его упрощал. А теперь уже не упрощаю, а работаю только с максимально упрощёнными кодами. Дашь упрощённый код?
0
Gepar
1177 / 533 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
10.12.2012, 01:06  [ТС] #8
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Если у тебя хотя бы два файла, в которых есть #include "colors.h"
Так он один, include "Colors.h" есть ТОЛЬКО в list.h, в list.cpp и main нет include "Colors.h" .
Плюс почему это
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
она включает всё это в каждый файл, где прописан этот инклуд.
У меня там ifndef endif макрос, если оно встретит во второй раз то оно не должно его включать.
Но я попробую сейчас воспользоваться твоим советом насчёт функций в Colors.h.


Цитата Сообщение от kravam Посмотреть сообщение
Прикинь, если бы ты весь код дал (а многие так и делают), я бы САМ весь его упрощал.
А толку упрощать, видно же что тупо две функции, а что они делают читать не надо же, пофиг ведь что там в них пописано.
0
DU
1483 / 1059 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
10.12.2012, 01:08 #9
если функция реализована в h файле, то чтобы не было ругани линковщика, перед функцией нужно явно просталять ключевое слово inline. или же, как было сказано, выносить реализацию в отдельный cpp файл. это актуально для свободных функций. шаблонные функции и методы вроде как автоматом в этом случае инлайновые.
0
Gepar
1177 / 533 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
10.12.2012, 01:09  [ТС] #10
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
А реализацию функций вынеси в СРР файл. Сolors.cpp
Таки помогло. Не понятно до конца только почему. Как же макросы и всё такое...
Получается я могу разнести код colors на .h и .cpp и оставить код list только в list.h, но я не могу оставить код colors в colors.h, а код list разнести на list.h и list.cpp. Неравноправие получается.
0
Kuzia domovenok
1891 / 1746 / 118
Регистрация: 25.03.2012
Сообщений: 5,925
Записей в блоге: 1
10.12.2012, 01:09 #11
Цитата Сообщение от Gepar Посмотреть сообщение
У меня там ifndef endif макрос, если оно встретит во второй раз то оно не должно его включать.
Вопрос в том, что за "ОНО" встретит его второй раз? Препроцессор, который эти дефайны обрабатывает? Ну да, но только если ты по ошибке два раза напишешь .
#include "colors.h"
#include "colors.h"
или вложишь один заголовок в другой.
Ведь препроцессор обрабатывает только ОДИН файл за раз. Он тупой как текстовый обработчик, ему интересен каждый раз один СРР файл + заголовки + пара твоих директив. О существовании других СРР файлов в момент обработки он не знает.
или что-то в этом роде. А к двум разным СРР файлам будет подключено по заголовку. Вот такие дела.
0
Croessmah
Эксперт CЭксперт С++
13214 / 7485 / 843
Регистрация: 27.09.2012
Сообщений: 18,401
Записей в блоге: 3
Завершенные тесты: 1
10.12.2012, 01:10 #12
Цитата Сообщение от Gepar Посмотреть сообщение
У меня там ifndef endif макрос, если оно встретит во второй раз то оно не должно его включать.
Но я попробую сейчас воспользоваться твоим советом насчёт функций в Colors.h.
CPP файлы компилируются раздельно и ничего не знают друг о друге. Поэтому в каждом файле, где включен color.h он будет включаться. А потом у линковщика возникают вопросы - какую из копий функции вызывать.

Цитата Сообщение от Gepar Посмотреть сообщение
Так он один, include "Colors.h" есть ТОЛЬКО в list.h, в list.cpp и main нет include "Colors.h" .
А list включается в main, да?
0
DU
1483 / 1059 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
10.12.2012, 01:16 #13
пока лист.h c функциями, которые прям там и реализованы включается в один спп файл, все будет хорошо. как только это включение попадает в 2 и более файла - появится та же проблема. еще раз обращаю внимание на ключевое слово инлайн, с которым все должно быть ок.

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
#ifndef COLORS_H
#define COLORS_H
 
#include<windows.h>
 
//коды цветов
enum ConsoleColor
{
        Black         = 0,
};
 
//возможность установки цвета зная заранее его код
inline void SetColor(ConsoleColor text,ConsoleColor background = White)
{
    static HANDLE hStdOut;
    SetConsoleTextAttribute(hStdOut, (WORD) 1);
}
 
//доп. возможность установкци цвета. Её отличие в том что функция
//выбирает цвета максимально отличающиеся для номеров что рядом (в отличии от распред. цветов в табличке)
inline void SetDifColors(int nColor)
{
    ConsoleColor color;
    SetColor(color);
}
#endif
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.12.2012, 01:16
Привет! Вот еще темы с ответами:

Файл сохраняется не туда, куда нужно. - Visual Basic
Есть код: ... Dim b As Boolean FF = Text1.Text b = CreateXlBook(&quot;FF&quot;, &quot;&quot;) ... Public Function CreateXlBook(sWbName As...

Консольные приложения куда то не туда перенаправлены - Windows XP
С некоторых пор консольные приложения по другому стали работать. Например Пуск-&gt;Выполнить-&gt;cmd раньше в окне открывался, теперь во весь...

Как установить программу не в /, а туда куда я хочу? - Linux
Вот например у меня есть пакет yum-3.4.3.tar.gz, как мне его установить не в систему, а какую-нибудь папку?

Перемещение квадрата туда куда кликнул мышкою - OpenGL
Добрый вечер! У меня возникла проблема, во время делания кода, который при клике мышки должен переместить квадрат туда куда кликнул. ...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
10.12.2012, 01:16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru