Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

не линкуется

87K
06 марта 2015 года
Achez
6 / / 06.03.2015
Я прошу прощения, что лезу со своими глупостями. Я впервые на подобном форуме. Я только начинаю изучать C/C++. Решил вот потренироваться, написать собственный класс для хранения даты. Всё работало, пока я не попытался добавить функцию увеличения даты на 1 день (с соответственным увеличением месяца, года при необходимости). Я сперва хотел сделать её в виде перегруженного оператора ++, но никак не хотело компилироваться. После попыток изменить тип возвращаемого значения или параметров появились ошибки линковки. Я переделал тогда функцию в обычный метод типа void без параметров, но ошибки не исчезли. Более того, ошибки не исчезли даже тогда, когда я полностью закомментировал эту новую функцию. Причём после начала работы с ней я не трогал ничего старого, а ошибки линковки указывают и на старые функции тоже. Чертовщина какая-то. Может, кто-нибудь более опытный увидит то, чего не вижу я? По алгоритму никаких вопросов нет. К сожалению, не могу привести короткий отрывок кода с ошибкой, потому что я не знаю, в каком файле и в каком месте ошибка - линковщик не даёт таких сведений. Могу только сказать, что все функции, кроме Inc(), уже отлажены и прекрасно работают. Ещё раз прошу прощения, возможно, мой вопрос не в формате данного форума, в таком случае буду очень благодарен за совет, куда можно обратиться с такими нубскими проблемами (гугл не предлагать, он хорошо только для поиска теории по конкретной теме, а запросы типа "почему не работает" не приводят к желаемому результату).

P.S. Прошу прощения также за слово fucking в коде, не ожидал, что придётся кому-то показывать, а исправлять страшно, ещё новых ошибок добавлю.

upd. 03-07. Программа линкуется, если полностью закомментировать описание функций operator<< и Inc() и удалить их объявления из объявления класса. Если ЗАКОММЕНТИРОВАТЬ объявления в объявлении класса - 6 ошибок линковки. Переношу ЗАКОММЕНТИРОВАННЫЕ объявления в конец файла, за пределы объявления класса - линкуется.

upd2 Закомментировал описания функций operator<< и Inc(), удалив их объявления из объявления класса. 6 ошибок линковки. Объединил два этих комментария в один, убрав символы ...*/ /*... - линкуется! Что за чертовщина творится?!
Код:
// main.cpp

#include "date.h"

#ifndef INC_IOS
#define INC_IOS
#include <iostream>
#endif

using namespace std;

int main()
{
    MyDate fuckingDate;
    int error;
    do
    {
        error=fuckingDate.KeybInput();
        cout << fuckingDate<<endl;
        fuckingDate.Inc();
        cout << fuckingDate<<endl;
    }
    while (!error);
    system("pause");
}
Код:
// date.cpp

#ifndef INC_IOS
#define INC_IOS
#include <iostream>
#endif

#include "date.h"

MyDate::MyDate()
{
    m_day = 1;
    m_month = 1;
    m_year = 1;
}

int MyDate::SetDay(int newDay)
// return codes: 0 - ok, 1 - too small, 2 - too big, 3 - february error
{
    if (newDay < 1)
        return 1;
    if (newDay > 31)
        return 2;
    if (newDay >30)
        switch (m_month)
        {
        case 2:
        case 4:
        case 6:
        case 9:
        case 11:
            return 2;
        default:
            ;
        }
    if ((newDay > 29) && (m_month == 2))
        return 3;
    if ( (newDay > 28) && (m_month == 2) && (!IsLeap()) )
        return 3;
    m_day = newDay;
    return 0;
}

int MyDate::SetMonth(int newMonth)
// error codes: 0 - ok, 1 - too small, 2 - too big, 3 - cannot be with current day
{
    if (newMonth < 1)
        return 1;
    if (newMonth > 12)
        return 2;
    if (m_day>30)
        switch (newMonth)
        {
        case 2:
        case 4:
        case 6:
        case 9:
        case 11:
            return 3;
        default:
            ;
        }
    if ((m_day > 29) && (newMonth == 2))
        return 3;
    if ((m_day > 28) && (newMonth == 2) && (!IsLeap()))
        return 3;
    m_month = newMonth;
    return 0;
}

int MyDate::SetYear(int newYear)
{
    if (!newYear)
        return 1;
    int old_year = m_year;
    m_year = newYear;
    if ( (m_day == 29) && (m_month == 2) )
        if (!IsLeap())
        {
            m_year = old_year;
            return 2;
        }
    return 0;
}

MyDate::MyDate(int newDay, int newMonth, int newYear)
{
    m_year = 1;
    m_month = 1;
    m_day = 1;
    if (SetYear(newYear))
        m_year = 1;
    if (SetMonth(newMonth))
        m_month = 1;
    if (SetDay(newDay))
        m_day = 1;
}

int MyDate::GetYear() const
{
    return m_year;
}

int MyDate::GetMonth() const
{
    return m_month;
}

int MyDate::GetDay() const
{
    return m_day;
}

bool MyDate::IsLeap()
{
    if (!(m_year % 400))
        return true;
    if ( (!(m_year % 4)) && (m_year % 100) )
        return true;
    return false;
}

ostream& operator<<(ostream& os, const MyDate& arg)
{
    switch (arg.GetMonth())
    {
    case 1:
        os << "January";
        break;
    case 2:
        os << "February";
        break;
    case 3:
        os << "March";
        break;
    case 4:
        os << "April";
        break;
    case 5:
        os << "May";
        break;
    case 6:
        os << "June";
        break;
    case 7:
        os << "July";
        break;
    case 8:
        os << "August";
        break;
    case 9:
        os << "September";
        break;
    case 10:
        os << "October";
        break;
    case 11:
        os << "November";
        break;
    case 12:
        os << "December";
        break;
    default:
        os << "Unknown fucking month";
    }
    os << " " << arg.GetDay() << ", " << arg.GetYear();
    return os;
}

bool MyDate::KeybInput()
{
    int error, buff;
    do
    {
        cout << "Enter year: ";
        cin >> buff;
        error = SetYear(buff);
        switch (error)
        {
        case 0:
            cout << "OK";
            break;
        case 1:
            cout << "Can't be zero!" << endl;
            //break;
            return true;
        case 2:
            cout << "It's february 29th and year can't be accepted!";
            break;
        }

        cout << endl;
    } while (error);

    do
    {
        cout << "Enter month: ";
        cin >> buff;
        error = SetMonth(buff);
        switch (error)
        {
        case 0:
            cout << "OK";
            break;
        case 1:
            cout << "Too small!";
            break;
        case 2:
            cout << "Too big!";
            break;
        case 3:
            cout << "Cannot be with curent day!";
            break;
        }
        cout << endl;
    } while (error);

    do
    {
        cout << "Enter day: ";
        cin >> buff;
        error = SetDay(buff);
        switch (error)
        {
        case 0:
            cout << "OK";
            break;
        case 1:
            cout << "Too small!";
            break;
        case 2:
            cout << "Too big!";
            break;
        case 3:
            cout << "Re-check leap year!";
            break;
        }
        cout << endl;
    } while (error);
    return false;
}

 void MyDate::Inc()
{
    if ((m_month == 12) && (m_day == 31))
    {
        m_month = 1;
        m_day = 1;
        if (m_year == -1)
            m_year = 1;
        else
            m_year++;
        return;
    }

    if (m_day > 30)
    {
        m_month++;
        m_day = 1;
        return;
    }

    if (m_day > 29)
        switch (m_month)
        {
        case 4:
        case 6:
        case 9:
        case 11:
            m_month++;
            m_day = 1;
            return;
        }

    if ((m_day > 28) && (m_month == 2))
    {
        m_day = 1;
        m_month++;
        return;
    }

    if ((m_day > 27) && (m_month == 2) && (!IsLeap()))
    {
        m_day = 1;
        m_month++;
        return;
    }

    m_day++;
    return;
}
Код:
// date.h

#ifndef INC_IOS
#define INC_IOS
#include <iostream>
#endif

using namespace std;

class MyDate
{
    unsigned char m_day;
    unsigned char m_month;
    int m_year;
public:
    MyDate(int newDay, int newMonth, int newYear);
    MyDate();
    int SetDay(int newDay);
    int SetMonth(int newMonth);
    int SetYear(int newYear);

    int GetDay() const;
    int GetMonth() const;
    int GetYear() const;

    bool IsLeap();

    bool KeybInput();

    void Inc();

    friend ostream& operator<<(ostream& os, const MyDate& arg);
};
Цитата:
Ошибка 6 error LNK1120: неразрешенных внешних элементов: 4 E:prjAnyDateDebugAnyDate.exe AnyDate
Ошибка 5 error LNK2019: ссылка на неразрешенный внешний символ "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class MyDate const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABVMyDate@@@Z) в функции _main E:prjAnyDatemain.obj AnyDate
Ошибка 2 error LNK2019: ссылка на неразрешенный внешний символ "public: __thiscall MyDate::MyDate(void)" (??0MyDate@@QAE@XZ) в функции _main E:prjAnyDatemain.obj AnyDate
Ошибка 3 error LNK2019: ссылка на неразрешенный внешний символ "public: bool __thiscall MyDate::KeybInput(void)" (?KeybInput@MyDate@@QAE_NXZ) в функции _main E:prjAnyDatemain.obj AnyDate
Ошибка 4 error LNK2019: ссылка на неразрешенный внешний символ "public: void __thiscall MyDate::Inc(void)" (?Inc@MyDate@@QAEXXZ) в функции _main E:prjAnyDatemain.obj AnyDate
Предупреждение 1 warning LNK4042: объект указан более одного раза; лишние не учитываются E:prjAnyDateDebugdate.obj 1 1 AnyDate

446
07 марта 2015 года
Meander
487 / / 04.09.2011
Приведенный код у Вас компилируется?
У меня в DevCpp он компилируется.
87K
07 марта 2015 года
Achez
6 / / 06.03.2015
Цитата: Meander
Приведенный код у Вас компилируется?
У меня в DevCpp он компилируется.

Он компилируется в объектники, а объектники в экзешник не линкуются.

326
07 марта 2015 года
sadovoya
757 / / 19.11.2005
Не знаю, как в студии, но в средах есть правила добавления классов, файлов в проект. При этом среда линковщику прописывает нужные сведения. Я вот к чему: может вы "не так" добавляли файлы, классы в проект студии...
87K
07 марта 2015 года
Achez
6 / / 06.03.2015
Цитата: sadovoya
Не знаю, как в студии, но в средах есть правила добавления классов, файлов в проект. При этом среда линковщику прописывает нужные сведения. Я вот к чему: может вы "не так" добавляли файлы, классы в проект студии...

Я не знаю всех правил, но заголовочные файлы я добавлял в категорию "заголовочные файлы", а файлы исходного кода в категорию "файлы исходного кода". Я всегда так делал, и обычно всё работает.
Вообще эти ошибки очень странные. Сейчас программа уже сильно отличается от того, что выложено выше, и эти ошибки продолжают возникать и исчезать от совершенно непонятных причин. Например, однажды я сразу после неудачной сборки удалил только одну пустую строку в начале файла date.h, больше НИЧЕГО не менял, честное слово - и всё скомпилировалось и слинковалось. То есть вроде как 6 ошибок создала одна пустая строка.

Сейчас все функции по отдельности отлажены и работают, но как только я их все использую в main, возникают ошибки линковки. Причём ошибки указывают на все функции, которые вызывает main.

Попробовал собрать в GCC - тоже ошибки линковки, но совершенно другие:

Цитата:
main.o:main.cpp:(.text+0x13f): undefined reference to `std::cout'
main.o:main.cpp:(.text+0x144): undefined reference to `std::ostream::operator<<(
long)'
main.o:main.cpp:(.text+0x157): undefined reference to `std::basic_ostream<char,
std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_o
stream<char, std::char_traits<char> >&, char const*)'
main.o:main.cpp:(.text+0x202): undefined reference to `std::cout'
main.o:main.cpp:(.text+0x207): undefined reference to `std::ostream::operator<<(
long)'
main.o:main.cpp:(.text+0x21a): undefined reference to `std::basic_ostream<char,
std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_o
stream<char, std::char_traits<char> >&, char const*)'
main.o:main.cpp:(.text+0x221): undefined reference to `std::basic_ostream<char,
std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_os
tream<char, std::char_traits<char> >&)'
main.o:main.cpp:(.text+0x228): undefined reference to `std::ostream::operator<<(
std::ostream& (*)(std::ostream&))'
main.o:main.cpp:(.text+0x272): undefined reference to `std::ios_base::Init::~Ini
t()'
main.o:main.cpp:(.text+0x293): undefined reference to `std::ios_base::Init::Init
()'
e:/apps/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: main.
o: bad reloc address 0x0 in section `.ctors'
e:/apps/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: final
link failed: Invalid operation
collect2.exe: error: ld returned 1 exit status

260
07 марта 2015 года
Ramon
1.1K / / 16.08.2003
Цитата: Achez
Цитата: sadovoya
Не знаю, как в студии, но в средах есть правила добавления классов, файлов в проект. При этом среда линковщику прописывает нужные сведения. Я вот к чему: может вы "не так" добавляли файлы, классы в проект студии...

Я не знаю всех правил, но заголовочные файлы я добавлял в категорию "заголовочные файлы", а файлы исходного кода в категорию "файлы исходного кода". Я всегда так делал, и обычно всё работает.
Вообще эти ошибки очень странные. Сейчас программа уже сильно отличается от того, что выложено выше, и эти ошибки продолжают возникать и исчезать от совершенно непонятных причин. Например, однажды я сразу после неудачной сборки удалил только одну пустую строку в начале файла date.h, больше НИЧЕГО не менял, честное слово - и всё скомпилировалось и слинковалось. То есть вроде как 6 ошибок создала одна пустая строка.

Сейчас все функции по отдельности отлажены и работают, но как только я их все использую в main, возникают ошибки линковки. Причём ошибки указывают на все функции, которые вызывает main.

Попробовал собрать в GCC - тоже ошибки линковки, но совершенно другие:

Цитата:
main.o:main.cpp:(.text+0x13f): undefined reference to `std::cout'
main.o:main.cpp:(.text+0x144): undefined reference to `std::ostream::operator<<(
long)'
main.o:main.cpp:(.text+0x157): undefined reference to `std::basic_ostream<char,
std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_o
stream<char, std::char_traits<char> >&, char const*)'
main.o:main.cpp:(.text+0x202): undefined reference to `std::cout'
main.o:main.cpp:(.text+0x207): undefined reference to `std::ostream::operator<<(
long)'
main.o:main.cpp:(.text+0x21a): undefined reference to `std::basic_ostream<char,
std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_o
stream<char, std::char_traits<char> >&, char const*)'
main.o:main.cpp:(.text+0x221): undefined reference to `std::basic_ostream<char,
std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_os
tream<char, std::char_traits<char> >&)'
main.o:main.cpp:(.text+0x228): undefined reference to `std::ostream::operator<<(
std::ostream& (*)(std::ostream&))'
main.o:main.cpp:(.text+0x272): undefined reference to `std::ios_base::Init::~Ini
t()'
main.o:main.cpp:(.text+0x293): undefined reference to `std::ios_base::Init::Init
()'
e:/apps/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: main.
o: bad reloc address 0x0 in section `.ctors'
e:/apps/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: final
link failed: Invalid operation
collect2.exe: error: ld returned 1 exit status

А вы вырубите антивирус и возможно обрящете.

87K
07 марта 2015 года
Achez
6 / / 06.03.2015
Цитата: Ramon
А вы вырубите антивирус и возможно обрящете.

С удовольствием бы вырубил, если б он у меня был. :)

326
07 марта 2015 года
sadovoya
757 / / 19.11.2005
Попробуйте сборку из студии 2010, прикрепил. У меня работает. В 2013 по идее должно тоже.
Файрвол и может тоже влиять.
Прикрепленные файлы:
3 Кб
Загрузок: 849
87K
07 марта 2015 года
Achez
6 / / 06.03.2015
Цитата: sadovoya
Попробуйте сборку из студии 2010, прикрепил. У меня работает. В 2013 по идее должно тоже.
Файрвол и может тоже влиять.

При попытке сборки студия не смогла найти CL.EXE.
Файрвола нет.
Сейчас уже нет смысла пытаться собирать ту версию моей программы, она безнадёжно устарела для меня, в ней появилось с десяток новых функций. И даже текущую версию я смог собрать, выбрав вместо сборки "анализ кода" (при этом команда "собрать" по-прежнему выдаёт ошибки линковки). Мне хотелось бы знать, что вызывает эти ошибки и как их избежать, не танцуя с бубном.

446
07 марта 2015 года
Meander
487 / / 04.09.2011
Может студия криво крякнута. Может директория со средой и с проектами не обладают правами администатора и система периодически не дает собираться проектам.
87K
07 марта 2015 года
Achez
6 / / 06.03.2015
Цитата: Meander
Может студия криво крякнута. Может директория со средой и с проектами не обладают правами администатора и система периодически не дает собираться проектам.

Студия бесплатная (Express Edition). Директория как таковая не имеет прав, бывает наоборот - у пользователя нет прав на запись в директорию. Но я сижу из-под админа, таким проблем быть не должно.

У меня всё собралось, как только я выбрал конфигурацию Release вместо Debug. Код не трогал. Сдаётся мне, багованная эта 13-я студия. Недаром под неё уже несколько сервис-паков вышло.

260
07 марта 2015 года
Ramon
1.1K / / 16.08.2003
Цитата: Achez
Цитата: Meander
Может студия криво крякнута. Может директория со средой и с проектами не обладают правами администатора и система периодически не дает собираться проектам.

Студия бесплатная (Expres Edition). Директория как таковая не имеет прав, бывает наоборот - у пользователя нет прав на запись в директорию. Но я сижу из-под админа, таким проблем быть не должно.

У меня всё собралось, как только я выбрал конфигурацию Release вместо Debug. Код не трогал. Сдаётся мне, багованная эта 13-я студия. Недаром под нё уже несколько сервис-паков вышло.

Expres Edition смело выносите в окно оно никогда не было рабочим.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог