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

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

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

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

09.12.2012, 23:55. Просмотров 1007. Ответов 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 ?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Kuzia domovenok
1889 / 1744 / 117
Регистрация: 25.03.2012
Сообщений: 5,922
Записей в блоге: 1
09.12.2012, 23:58     Линковщик студии суёт нос не туда куда надо #2
Цитата Сообщение от Gepar Посмотреть сообщение
Ошибка 1 error LNK2005: "void __cdecl SetColor(enum ConsoleColor,enum ConsoleColor)" (?SetColor@@YAXW4ConsoleColor@@0@Z) єцх юяЁхфхыхэ т List.obj
У тебя что? Студия русифицирована? Зря. Очень зря. Знатоком английского, чтоб разбираться в ней быть не надо. А подобные сообщения гуглить и вообще искать информацию о студии на порядок тяжелее!
kravam
быдлокодер
1691 / 878 / 44
Регистрация: 04.06.2008
Сообщений: 5,420
10.12.2012, 00:18     Линковщик студии суёт нос не туда куда надо #3
Цитата Сообщение от Gepar Посмотреть сообщение
Теперь я добавляю List.cpp файл и выношу туда одну функцию из класса List что описан в List.h
То есть тут перегрузкой не пахнет; но

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

Короче код нужен.
Gepar
1175 / 531 / 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 то ничего не поменяется
go
Эксперт C++
3586 / 1366 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
10.12.2012, 00:34     Линковщик студии суёт нос не туда куда надо #5
Gepar, .h только прототип.
Kuzia domovenok
1889 / 1744 / 117
Регистрация: 25.03.2012
Сообщений: 5,922
Записей в блоге: 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);
}
- ошибка исчезнет
kravam
быдлокодер
1691 / 878 / 44
Регистрация: 04.06.2008
Сообщений: 5,420
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
Прикинь, если бы ты весь код дал (а многие так и делают), я бы САМ весь его упрощал. А теперь уже не упрощаю, а работаю только с максимально упрощёнными кодами. Дашь упрощённый код?
Gepar
1175 / 531 / 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 Посмотреть сообщение
Прикинь, если бы ты весь код дал (а многие так и делают), я бы САМ весь его упрощал.
А толку упрощать, видно же что тупо две функции, а что они делают читать не надо же, пофиг ведь что там в них пописано.
DU
1480 / 1056 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
10.12.2012, 01:08     Линковщик студии суёт нос не туда куда надо #9
если функция реализована в h файле, то чтобы не было ругани линковщика, перед функцией нужно явно просталять ключевое слово inline. или же, как было сказано, выносить реализацию в отдельный cpp файл. это актуально для свободных функций. шаблонные функции и методы вроде как автоматом в этом случае инлайновые.
Gepar
1175 / 531 / 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. Неравноправие получается.
Kuzia domovenok
1889 / 1744 / 117
Регистрация: 25.03.2012
Сообщений: 5,922
Записей в блоге: 1
10.12.2012, 01:09     Линковщик студии суёт нос не туда куда надо #11
Цитата Сообщение от Gepar Посмотреть сообщение
У меня там ifndef endif макрос, если оно встретит во второй раз то оно не должно его включать.
Вопрос в том, что за "ОНО" встретит его второй раз? Препроцессор, который эти дефайны обрабатывает? Ну да, но только если ты по ошибке два раза напишешь .
#include "colors.h"
#include "colors.h"
или вложишь один заголовок в другой.
Ведь препроцессор обрабатывает только ОДИН файл за раз. Он тупой как текстовый обработчик, ему интересен каждый раз один СРР файл + заголовки + пара твоих директив. О существовании других СРР файлов в момент обработки он не знает.
или что-то в этом роде. А к двум разным СРР файлам будет подключено по заголовку. Вот такие дела.
Croessmah
Модератор
Эксперт CЭксперт С++
12979 / 7291 / 812
Регистрация: 27.09.2012
Сообщений: 18,007
Записей в блоге: 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, да?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.12.2012, 01:16     Линковщик студии суёт нос не туда куда надо
Еще ссылки по теме:
две студии C++
C++ с Клавиатуры надо ввести имена 5 человек , надо найти сколько гласных букв в каждом имени человека
C++ дебагер в студии 2010
C++ Происходит ли установка студии?
C++ Ошибка с гетлайн в студии 2010

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

Или воспользуйтесь поиском по форуму:
DU
1480 / 1056 / 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
Yandex
Объявления
10.12.2012, 01:16     Линковщик студии суёт нос не туда куда надо
Ответ Создать тему
Опции темы

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