powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Ошибка линковки при объявлении функции А в определении функции Б.
13 сообщений из 13, страница 1 из 1
Ошибка линковки при объявлении функции А в определении функции Б.
    #38302076
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброго времени суток.

Приведённый ниже код успешно компилируется:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
	Point get_offset_point(Point,double,double);
//---------------------------------------------------------------------------
	Arrow::Arrow(Point p0, double angle, double length, Arrow_style style): 
		ang(angle), len(length), s(style){
			Point p1 = get_offset_point(p0,angle,length);
			Point p2 = get_offset_point(p0,angle+10,length/2);
			Point p3 = get_offset_point(p0,angle-10,length/2);

			// стрелка указывает:			
			add(p0); // куда
			add(p1); // откуда
			// засечки
			add(p2);
			add(p3);
	}


Однако, я хочу объявление функции get_offset_point переместить в определение Arrow::Arrow, т.к. она используется только в этом конструкторе. Пишу так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
//---------------------------------------------------------------------------
	Arrow::Arrow(Point p0, double angle, double length, Arrow_style style): 
		ang(angle), len(length), s(style){

			Point get_offset_point(Point,double,double);

			Point p1 = get_offset_point(p0,angle,length);
			Point p2 = get_offset_point(p0,angle+10,length/2);
			Point p3 = get_offset_point(p0,angle-10,length/2);

			// стрелка указывает:			
			add(p0); // куда
			add(p1); // откуда
			// засечки
			add(p2);
			add(p3);
	}


Однако в результате получаю ошибку линковки:
Errors
Error 85 error LNK1120: 1 unresolved externals C:\bs\13\ch13\Debug\ch13.exe 1 1 ch13
Error 84 error LNK2019: unresolved external symbol "struct Point __cdecl get_offset_point(struct Point,double,double)" (?get_offset_point@@YA?AUPoint@@U1@NN@Z) referenced in function "public: __thiscall Bushman::Arrow::Arrow(struct Point,double,double,struct Bushman::Arrow_style)" (??0Arrow@Bushman@@QAE@UPoint@@NNUArrow_style@1@@Z) C:\bs\13\ch13\arrow.obj ch13


Почему линковщик не находит функцию во втором варианте?

Спасибо.
...
Рейтинг: 0 / 0
Ошибка линковки при объявлении функции А в определении функции Б.
    #38302133
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CompositumОднако, я хочу объявление функции get_offset_point переместить в определение Arrow::Arrow, т.к. она используется только в этом конструкторе.В С++ не бывает вложенных функций.
Если хочешь ограничить видимость, вынеси конструктор в отдельный .cpp, положи рядом эту функцию и объяви ее static.

А вообще, зачем тебе глобальная функция с ограниченной видимостью? То что ты хочешь обычно делают через приватные функции или приватные классы.
...
Рейтинг: 0 / 0
Ошибка линковки при объявлении функции А в определении функции Б.
    #38302140
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlВ С++ не бывает вложенных функций.

Это не вложеная функция, а вложенный прототип функции - второе разрешено.
...
Рейтинг: 0 / 0
Ошибка линковки при объявлении функции А в определении функции Б.
    #38302149
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробовал прописать полное имя, получил ещё более странные ошибки.
Код
Код: plaintext
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.
/*
arrow.cpp
© Andrey Bushman, 18 Jun 2013
Chapter 13, exercise 3.
*/
//---------------------------------------------------------------------------
#include "arrow.h"
//*****************************************************************************
namespace Bushman{
	// Point get_offset_point(Point,double,double);
//---------------------------------------------------------------------------
	Arrow::Arrow(Point p0, double angle, double length, Arrow_style style): 
		ang(angle), len(length), s(style){

			Point Bushman::get_offset_point(Point,double,double);

			Point p1 = Bushman::get_offset_point(p0,angle,length);
			Point p2 = Bushman::get_offset_point(p0,angle+10,length/2);
			Point p3 = Bushman::get_offset_point(p0,angle-10,length/2);

			// стрелка указывает:			
			add(p0); // куда
			add(p1); // откуда
			// засечки
			add(p2);
			add(p3);
	}
//---------------------------------------------------------------------------
	Point get_offset_point(Point p0, double angle, double length){

		if(length < 0) 
			throw runtime_error("Invalid length value: " + to_string(length));

		if(angle > 360 || angle < -360) 
			throw runtime_error("Invalid angle value: " + to_string(angle));

		if(angle < 0) angle = 360 - abs(angle);

		// если угол не прямой, то переводим его в радианы.
		if(angle != 0 && angle != 90 && angle != 180 && angle != 270) 
			angle *= 3.14159265/180;

		// Определяю начало стрелки	(точка p1)	
		Point p1;
		if(angle == 0 || angle == 360){
			p1.x = p0.x + length;
			p1.y = p0.y;
		}
		else if(angle < 90){
			p1.x = p0.x + length * cos(angle);
			p1.y = p0.y - length * sin(angle);
		}
		else if(angle == 90){
			p1.y = p0.y - length;
			p1.x = p0.x;
		}
		else if(angle < 180){
			p1.x = p0.x - length * cos(180 - angle);
			p1.y = p0.y - length * sin(180 - angle);
		}
		else if(angle == 180){
			p1.x = p0.x - length;
			p1.y = p0.y;
		}
		else if(angle < 270){
			p1.x = p0.x - length * cos(270 - angle);
			p1.y = p0.y + length * sin(270 - angle);
		}
		else if(angle == 270){
			p1.x = p0.x;
			p1.y = p0.y + length;
		}		
		else if(angle < 360){
			p1.x = p0.x + length * cos(360 - angle);
			p1.y = p0.y + length * sin(360 - angle);
		}
		return p1;
	}
}



Errors
Error 33 error C2039: 'get_offset_point' : is not a member of 'Bushman' c:\bs\13\ch13\arrow.cpp 15 1 ch13
Error 34 error C2039: 'get_offset_point' : is not a member of 'Bushman' c:\bs\13\ch13\arrow.cpp 17 1 ch13
Error 35 error C2039: 'get_offset_point' : is not a member of 'Bushman' c:\bs\13\ch13\arrow.cpp 18 1 ch13
Error 36 error C2039: 'get_offset_point' : is not a member of 'Bushman' c:\bs\13\ch13\arrow.cpp 19 1 ch13

Странно, ведь функция находится именно в том пространстве имён, которое я указал... Вроде делаю по правилам: объявил, прежде чем использовал, причём сделал это даже в стиле C (разместил объявление в самом начале кода).
авторВ С++ не бывает вложенных функций.

Я в курсе. Кроме того, в моём коде их и нет.
авторЕсли хочешь ограничить видимость, вынеси конструктор в отдельный .cpp, положи рядом эту функцию и объяви ее static.

Я знаю об этом способе. Однако меня всё же интересует, почему на заработал способ, указанный мною.
White OwlА вообще, зачем тебе глобальная функция с ограниченной видимостью? То что ты хочешь обычно делают через приватные функции или приватные классы.

Функцию стоит делать приватной лишь в том случае, если для её работы необходим доступ к закрытым членам класса. В моём случае такой необходимости нет.
...
Рейтинг: 0 / 0
Ошибка линковки при объявлении функции А в определении функции Б.
    #38302151
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CompositumФункцию стоит делать приватной лишь в том случае, если для её работы необходим доступ к закрытым членам класса. В моём случае такой необходимости нет.
очепятка. Правильно так:
CompositumФункцию стоит включать в состав интерфейса лишь в том случае, если для её работы необходим доступ к закрытым членам класса. В моём случае такой необходимости нет.
...
Рейтинг: 0 / 0
Ошибка линковки при объявлении функции А в определении функции Б.
    #38302165
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CompositumСтранно, ведь функция находится именно в том пространстве имён, которое я
указал...
Нет. В лучшем случае она в Bushman::Arrow.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Ошибка линковки при объявлении функции А в определении функции Б.
    #38302174
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovНет. В лучшем случае она в Bushman::Arrow.
С какого перепугу? В интерфейс я её не включал:
интерфейс
Код: plaintext
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.
/*
arrow.h
© Andrey Bushman, 18 Jun 2013
Chapter 13, exercise 3.
*/
//---------------------------------------------------------------------------
#ifndef BUSH_ARROW_H
#define BUSH_ARROW_H
#include "../Point.h"
#include "../Graph.h"
//*****************************************************************************
namespace Bushman{
//---------------------------------------------------------------------------
	struct Arrow_style{
		enum Arrow_style_type{ none, lines, filled, unfilled};
		Arrow_style(Arrow_style_type style): s(style) {}
		Arrow_style_type style() const { return s; }
	private:
		Arrow_style_type s;
	};
//---------------------------------------------------------------------------
	class Arrow: public Graph_lib::Shape 
	// Arrow
	{
	public:
		Arrow(Point p0, double angle, double length, Arrow_style style);
		void draw_lines() const;
		double angle() const { return ang; }
		double length() const { return len; }
		void set_angle(double val) { ang = val; }
		void set_length(double val) { len = val; }
		Arrow_style style() const { return s; }
		void set_style(Arrow_style val) { s = val; }
	private:		
		double ang,len;
		Arrow_style s; 
	};
}
#endif


...
Рейтинг: 0 / 0
Ошибка линковки при объявлении функции А в определении функции Б.
    #38302178
В принципе так можно.
http://ideone.com/UaWCBh

Compositum , у вас функция get_offset_point():
1. не является членом класса
2. не объявлена как static
3. не объявлена как inline
?
...
Рейтинг: 0 / 0
Ошибка линковки при объявлении функции А в определении функции Б.
    #38302181
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
не: static, inline, член классаВ принципе так можно.
http://ideone.com/UaWCBh

Compositum , у вас функция get_offset_point():
1. не является членом класса
2. не объявлена как static
3. не объявлена как inline
?
"да" по всем трём.
...
Рейтинг: 0 / 0
Ошибка линковки при объявлении функции А в определении функции Б.
    #38302216
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
не: static, inline, член классаВ принципе так можно.
http://ideone.com/UaWCBh
Я показывал несколько иной вариант. То, что в функциях можно размещать объявления др. функций, я в курсе, т.к. сам это неоднократно делал ранее.

Упрощённо, вот вариант, демонстрирующий обозначенную мною проблему кратко и наглядно:
Код: plaintext
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.
/*
test.cpp
© Andrey Bushman, 18 Jun 2013
*/
//--------------------------------------------
#include <exception>
#include <iostream>
using namespace std;
//--------------------------------------------
namespace Bushman{
//--------------------------------------------
	class MyClass{
	public:
		MyClass();
	};
//--------------------------------------------
	MyClass::MyClass(){
		void func(); // объявил
		func(); // вызвал
	}
//--------------------------------------------
	void func(){
		cout << "Ping..." << endl;
	}
}
//============================================
int main()
try{
	namespace B = Bushman;
	B::MyClass a;
}
catch(exception& e){
	cerr << e.what() << endl;
	return 1;
}
catch(...){
	cerr << "Unknown exception." << endl;
	return 2;
}


Во время компиляции (MS VS 2012) получаю такой результат:
LinkC:\bs\13>cl test.cpp /EHsc
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.51106.1 for x64
Copyright (C) Microsoft Corporation. All rights reserved.

test.cpp
Microsoft (R) Incremental Linker Version 11.00.51106.1
Copyright (C) Microsoft Corporation. All rights reserved.

/out:test.exe
test.obj
test.obj : error LNK2019: unresolved external symbol "void __cdecl func(void)" (
?func@@YAXXZ) referenced in function "public: __cdecl Bushman::MyClass::MyClass(
void)" (??0MyClass@Bushman@@QEAA@XZ)
test.exe : fatal error LNK1120: 1 unresolved externals

C:\bs\13>
...
Рейтинг: 0 / 0
Ошибка линковки при объявлении функции А в определении функции Б.
    #38302242
Сейчас проверил, в GCC 4.3.2/4.7.2 компилируется, в MSVS 2010/2012 ругается.
Хз в чем затык, то ли по стандарту надо как-то по другому делать, то ли MSVS стандарт не держит.
...
Рейтинг: 0 / 0
Ошибка линковки при объявлении функции А в определении функции Б.
    #38302253
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По стандарту, если прототип объявлен внутри функции находящейся в неймспейсе, то у прототипа будет тот же неймспейс.
А в вашем случае VS считает его глобальным.
Т.е. это баг в VS.
...
Рейтинг: 0 / 0
Ошибка линковки при объявлении функции А в определении функции Б.
    #38302255
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,

Здесь как-то тоже больше склоняются к тому, что это специфично для MS VS.
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Ошибка линковки при объявлении функции А в определении функции Б.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]