Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Вопрос по препроцессору: возможно проверить что был include в другом cpp ? / 25 сообщений из 25, страница 1 из 1
08.01.2016, 16:07
    #39143392
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
Например есть header.h
Код: plaintext
1.
2.
3.
4.
5.
#pragma once
void my_func()
{
 ...
}


Пока у меня один CPP проблем нет, а он у меня обычно один, например first.cpp
Код: plaintext
1.
2.
3.
4.
#include "header.h"
...
my_func();
...


Но если надо добавить second.cpp
Код: plaintext
1.
2.
3.
4.
#include "header.h"
...
my_func();
...


то начинаются ошибки линковки
Код: plaintext
1.
Error	LNK2005	"my_func()" (?my_func@@YAIPAXII@Z) already defined in first.obj



Можно конечно на все функции в header.h дописать inline, только не надо.

Вариант делать как положено с выносом тела в my_func.cpp не нравится, т.к. в новый проект придется все эти CPP добавлять, а их много. Повторюсь: в большинстве случаев проект из одного cpp и проблемы нет.

Может есть в препроцессоре какая-нибудь доп.проверка чтобы что-то типа такого можно было написать в header.h
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
#pragma once
#ifdef INCLUDE_IN_OTHER_MODULE
void my_func();
#else
void my_func()
{
 ...
}
#endif


Надо для MSVC 2015 и GCC
...
Рейтинг: 0 / 0
08.01.2016, 16:14
    #39143395
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
Оберни свою функцию в темплейт.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
08.01.2016, 16:43
    #39143410
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
Написал так
Код: plaintext
1.
2.
3.
4.
template< typename T >
void my_func()
{
 ...


Не компилируется
Код: plaintext
1.
2.
Error	C2672	'my_func': no matching overloaded function found	
Error	C2783	'void my_func(void)': could not deduce template argument for 'T'
...
Рейтинг: 0 / 0
08.01.2016, 16:47
    #39143413
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
Убери аргумент.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
08.01.2016, 16:54
    #39143416
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
Dima T,

Если функция в хедере, то ее тело будет включено в каждую единицу трансляции, куда хедер включен.
С этим вам нужно смириться.

Остается устранить ошибки при линковке, связанные с дублированием функции.

1) Пометить функцию как static
2) Поместить функцию в анонимный неймспейс namespace {}
3) Поместить функцию в класс.

1 работает и для С и для С++, а 2 и 3 соответственно только для С++.

Судя по всему у вас С++. В этом случае я бы выбрал способ 2, т.к. он во-первых рекомендуется как замена static, во-вторых все определения можно просто поместить внутрь namespace {} без редактирования, что намного упрощает процедуру.
...
Рейтинг: 0 / 0
08.01.2016, 16:55
    #39143418
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
Как?

Пробовал так
Код: plaintext
1.
2.
template< typename >
void my_func()



Код: plaintext
1.
2.
template< >
void my_func()


не компилируется.

Как понимаю надо наоборот добавить аргумент.
Так работает
Код: plaintext
1.
2.
3.
4.
template <typename T>
void my_func(T x)
{
 ...


вызов
Код: plaintext
1.
my_func(0);


только это как-то черезжопно.
...
Рейтинг: 0 / 0
08.01.2016, 17:16
    #39143436
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
Anatoly Moskovsky1) Пометить функцию как static
2) Поместить функцию в анонимный неймспейс namespace {}
Спасибо. Оба варинта пригодятся.

Некоторые функции такие:
Код: plaintext
1.
2.
3.
4.
void my_func()
{
  static int k = 0;
 ...


тут с namespace две разные k создаются.

Anatoly Moskovsky3) Поместить функцию в класс.
Если я правильно помню, помещение метода в класс равносильно inline ?
Код: plaintext
1.
2.
3.
4.
5.
6.
class X {
 void my_method() {
  ...
 }
 ...
}


т.е. my_method() будет всегда инлайнится в вызывающий код. Или я неправильно понимаю?
...
Рейтинг: 0 / 0
08.01.2016, 17:23
    #39143446
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
Dima TЕсли я правильно помню, помещение метода в класс равносильно inline ?
Нет, это равносильно помещению его в namespace.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
08.01.2016, 17:27
    #39143449
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
Dima TНекоторые функции такие:
Код: plaintext
1.
2.
3.
4.
void my_func()
{
  static int k = 0;
 ...



тут с namespace две разные k создаются.
Со static тоже. И это логично.
Если вам нужен только один экземпляр функции, то наверно надо использовать inline. Если я правильно помню.

Dima TЕсли я правильно помню, помещение метода в класс равносильно inline ?

Да.
Dima Tт.е. my_method() будет всегда инлайнится в вызывающий код. Или я неправильно понимаю?
Нет.
inline в С++ не означает что метод будет заинлайнен. Это просто подсказка компилятору про возможность инлайна.
...
Рейтинг: 0 / 0
08.01.2016, 18:12
    #39143484
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
Anatoly MoskovskyСо static тоже. И это логично.
Если вам нужен только один экземпляр функции, то наверно надо использовать inline. Если я правильно помню.
Все правильно: static и namespace одинаковы. Две разные k.

Это я коряво затестил. Был inline

C inline один экземпляр k, т.е. так
Код: plaintext
1.
2.
3.
4.
inline void my_func()
{
  static int k = 0;
 ...
...
Рейтинг: 0 / 0
14.01.2016, 10:38
    #39147051
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
В продолжение этой же темы. Надо static переменную в классе

Можно написать так (в header.h)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
namespace {
	class Test {
		static int x;
	public:
		Test() {
			x++;
			printf("%d\n", x);
		}
	};

	int Test::x = 0;
}


Без namespace не компилируется, с ним ожидаемо получил два разных Test::x в разных .cpp

так все нормально (общий x на оба .cpp)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
class Test {
	int& x = get_x();

	int& get_x() {
		static int x = 0;
		return x;
	}

public:
	Test() {
		x++;
		printf("%d\n", x);
	}
};


В принципе можно и так оставить, лишних букв немого добавилось, но как-то коряво смотрится.
Может есть какая-нибудь хитрость чтобы первый вариант заработал как надо без namespace ?
...
Рейтинг: 0 / 0
14.01.2016, 11:32
    #39147107
CEMb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
а ключевое слово extern, интересно, тут сработает?
...
Рейтинг: 0 / 0
14.01.2016, 12:10
    #39147149
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
Dima TМожет есть какая-нибудь хитрость чтобы первый вариант заработал как надо без namespace ?нужно в .cpp-файл инициализацию Test::x вынести
...
Рейтинг: 0 / 0
14.01.2016, 12:30
    #39147184
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
CEMbа ключевое слово extern, интересно, тут сработает?
Если я его правильно понимаю, extern не может быть вместе с присвоением, т.е. такое невозможно
Код: plaintext
1.
extern int Test::x = 0;


не компилируется.
Может еще куда его попробовать написать?
эти не компилируются
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
	class Test {
		static int x;
	public:
		Test() {
			x++;
			printf("%d\n", x);
		}
	};

	extern int Test::x = 0; // Error	C2720	'Test::x': 'extern ' storage-class specifier illegal on members



тут куча ошибок:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
	class Test {
		extern static int x;
	public:
		Test() {
			x++;
			printf("%d\n", x);
		}
	};

	int Test::x = 0;


Компилируется и правильно работает если вынести в один из .cpp
Код: plaintext
1.
int Test::x = 0;



Но это еще хуже чем вариант под спойлером 18676601 т.к. как уже писал в основном один .cpp в проекте и проблемы нет.
...
Рейтинг: 0 / 0
14.01.2016, 13:04
    #39147241
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
Глупый вопрос, а нафига нужно в .H имплементацию методов запихивать?

Не проще из .H имплементацию перенести в отдельный .C/.CPP файл, а в .H, как и положено, оставить только объявление метода?
...
Рейтинг: 0 / 0
14.01.2016, 13:13
    #39147249
CEMb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
А, нет, extern тут только всё запутает.

extern пугает компилятор, что реальное объявление будет в _другом_ месте. Т.е. кроме самого написания extern, нужно ещё объявление переменной в другом месте.
...
Рейтинг: 0 / 0
14.01.2016, 13:14
    #39147250
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
Leonid KudryavtsevГлупый вопрос, а нафига нужно в .H имплементацию методов запихивать?
чтобы написать
Код: plaintext
1.
#include <header.h>


и не заморачиваться на поиски .cpp для добавления в проект. Тем более что в этом h могут быть другие h упомянуты, у тех свои .cpp

Проекты у меня небольшие, общего много.
...
Рейтинг: 0 / 0
14.01.2016, 13:21
    #39147262
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
Странные какие-то "не заморачиваться".

Всю жизнь давал .H и .CPP одинаковые имена. Никогда проблемы "добавить в проект" не было. Один раз добавил и на всю жизнь проекта дальше живешь счастливо. В конце концов, добавить все библиотечные .CPP скопом. AFAIK неиспользуемый код линковшик сам выбросит.
...
Рейтинг: 0 / 0
14.01.2016, 13:29
    #39147280
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
А ещё люди давным-давно придумали библиотеки.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
14.01.2016, 13:44
    #39147301
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
У меня тоже одноименные H и CPP. Но они могут по разным папкам живут. Например в одной общие для всех проектов, во второй для группы проектов, в третьей для конкретного проекта.
Понятно что не смертельно потратить 10 сек на поиски нужной папки. Но еще лучше если не надо.

И во-вторых: мне удобнее когда все в одном месте, а не размазано по двум файлам. Мысль собрать все вместе навеяна C# там именно так.

PS Я на С/С++ немного пишу, некоторые вещи тут не так как везде, поэтому хочется унифицировать по возможности.
...
Рейтинг: 0 / 0
14.01.2016, 15:34
    #39147431
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
Этот вариант тоже не взлетел :(
Dima T
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
class Test {
	int& x = get_x();

	int& get_x() {
		static int x = 0;
		return x;
	}

public:
	Test() {
		x++;
		printf("%d\n", x);
	}
};



Есть еще static метод (функция потока), а оттуда по нормальному не достучаться до x

Похоже придется сделать CPP для этого случая
...
Рейтинг: 0 / 0
14.01.2016, 15:46
    #39147439
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
Победил. Так компилируется и работает правильно
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
class Test {
	int& x = get_x();

	static int& get_x() {
		static int x = 0;
		return x;
	}

public:
	Test() {
		x++;
	}

	static void print() {
		int& x = get_x();
		printf("%d\n", x);
	}
};
...
Рейтинг: 0 / 0
14.01.2016, 16:38
    #39147523
ДохтаР
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
Все гораздо проще ,
содержимое h файла заклчается в церебер вклчения.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
#ifndef  unit_cerber_h
#define unit_cerber_h

//bla bla bla  of unit.h

#endif
//EOF



Куда бы вы этот h файл не добавляли внутри проекта
и сколько угодно раз
цербер включения пропустит в линковку содержимое
этого h файла только один раз.
...
Рейтинг: 0 / 0
14.01.2016, 16:48
    #39147535
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
ДохтаР,

Код: plaintext
1.
#pragma once


это тоже самое. Только букв меньше. Стоит первой строчкой.

Затестил церберов, не помогло.
...
Рейтинг: 0 / 0
14.01.2016, 17:17
    #39147574
ДохтаР
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по препроцессору: возможно проверить что был include в другом cpp ?
Dima TДохтаР,

Код: plaintext
1.
#pragma once


это тоже самое. Только букв меньше. Стоит первой строчкой.

Затестил церберов, не помогло.

Это должно быть в cpp файле.
Код: plaintext
1.
2.
3.
4.
void my_func()
{
 ...
}



Релазизацию функции вынесите в cpp
в h оставьте только декларацию.

Оно так задумывалось , что бы и вы и линкер
смотрели в h файлы как в справочник -содержание,
а простыни c реализацией должны быть в cpp.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Вопрос по препроцессору: возможно проверить что был include в другом cpp ? / 25 сообщений из 25, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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