powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / ODR:Почему глобально и в namespace надо static для функций в .h-файле, а в struct не надо?
18 сообщений из 18, страница 1 из 1
ODR:Почему глобально и в namespace надо static для функций в .h-файле, а в struct не надо?
    #38597379
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вопрос про ODR (One Defenition Rule).
Есть следующий код:
file1.h
Код: 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.
#pragma once

// require static
static int func(int val) {
	return val*2;
}

// not require static
template<typename T>
T func_template(T val) {
	return func( val );
}

namespace N {

	// require static
	static int func(int val) {
		return val*2;
	}

	// not require static
	template<typename T>
	T func_template(T val) {
		return func( val );
	}
}


struct T {

	// not require static
	int func(int val) {
		return val*2;
	}

	// not require static
	template<typename T>
	T func_template(T val) {
		return func( val );
	}
};



file1.cpp
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
#include "file1.h"


int global_func1(int val) {
	return func_template<int>( val );
}


int global_func2(int val) {
	T t;
	return t.func_template<int>( val );
}



main.cpp
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
#include "file1.h"


int main() {
	
	int val = 1;
	func_template<int>( val );

	T t;
	t.func_template<int>( val );
	
	return 0;
}



Для шаблонных функций никогда нет необходимости ставить static (т.е. static для шаблонных функций всегда ставится автоматом?).

Но почему для обычных функций (глобальных и в namespace-е) необходим static если они в .h-файле, а для функций в struct/class не нужен static, в чем логика?
...
Рейтинг: 0 / 0
ODR:Почему глобально и в namespace надо static для функций в .h-файле, а в struct не надо?
    #38597505
Mozok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася Уткин,

Во-первых, по стандарту .
Во-вторых, вполне логично, учитывая, что шаблоны инстанциируются
только при первом использовании, а структуры вообще не отражаются
на результирующем коде.
...
Рейтинг: 0 / 0
ODR:Почему глобально и в namespace надо static для функций в .h-файле, а в struct не надо?
    #38597507
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MozokВася Уткин,

Во-первых, по стандарту .
Во-вторых, вполне логично, учитывая, что шаблоны инстанциируются
только при первом использовании, а структуры вообще не отражаются
на результирующем коде.
Один шаблон инстанцируется в каждой единице трансляции , где используется. По этому static нужен, просто он подразумевается автоматически.
Функция в структуре, а точнее в классе, разве не отражается на результирующем коде?
...
Рейтинг: 0 / 0
ODR:Почему глобально и в namespace надо static для функций в .h-файле, а в struct не надо?
    #38597512
Mozok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася Уткин,

Вася УткинОдин шаблон инстанцируется в каждой единице трансляции, где используется. По этому static нужен, просто он подразумевается автоматически.
Да нет там никакого автоматического статика. Я же специально ссылку на стандарт привел,
там все написано. У шаблонов точно такой же external linkage, как и у обычных функций.
Вася УткинФункция в структуре, а точнее в классе, разве не отражается на результирующем коде?
Да, неудачно выразился. Определение структуры - это определение её полей и объявление
методов. Определять методы не обязательно. Имелось в виду, что поля в конечном коде
будут представлены в виде каких-то сдвигов адресов и все. И кстати, объявление функции
членом структуры никак не отражается на самой структуре. Ну ладно, виртуальной отражается,
но это уже детали реализации компиляторов.
...
Рейтинг: 0 / 0
ODR:Почему глобально и в namespace надо static для функций в .h-файле, а в struct не надо?
    #38597520
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MozokВася Уткин,

Вася УткинОдин шаблон инстанцируется в каждой единице трансляции, где используется. По этому static нужен, просто он подразумевается автоматически.
Да нет там никакого автоматического статика. Я же специально ссылку на стандарт привел,
там все написано. У шаблонов точно такой же external linkage, как и у обычных функций.
Т.е. шаблонная функция инстанцируется только в одной из единиц трансляции, а в остальных идет обращение через external?
И как тогда компилятор определяет в какой из единиц трансляции инстанцировать? В C/C++ же раздельная компиляция.
...
Рейтинг: 0 / 0
ODR:Почему глобально и в namespace надо static для функций в .h-файле, а в struct не надо?
    #38597532
Mozok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася УткинТ.е. шаблонная функция инстанцируется только в одной из единиц трансляции, а в остальных идет обращение через external?

Нет. При каждом использовании в новой единице трансляции будет создан новый экземпляр.
Вася УткинИ как тогда компилятор определяет в какой из единиц трансляции инстанцировать?
Никак. Это не его задача.
...
Рейтинг: 0 / 0
ODR:Почему глобально и в namespace надо static для функций в .h-файле, а в struct не надо?
    #38597544
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MozokВася УткинТ.е. шаблонная функция инстанцируется только в одной из единиц трансляции, а в остальных идет обращение через external?

Нет. При каждом использовании в новой единице трансляции будет создан новый экземпляр.
Т.е. если в нескольких единицах трансляции имеется по экземпляру одной и той же функции, то это не нарушает ODR?
(например, если шаблонная функция инстанцированая в каждой единице трансляции с одним и тем же типом)
...
Рейтинг: 0 / 0
ODR:Почему глобально и в namespace надо static для функций в .h-файле, а в struct не надо?
    #38597553
Mozok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася Уткин,

ну я же привел ссылку на стандарт. Там все написано.
...
Рейтинг: 0 / 0
ODR:Почему глобально и в namespace надо static для функций в .h-файле, а в struct не надо?
    #38597563
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MozokВася Уткин,

ну я же привел ссылку на стандарт. Там все написано.
Ок. Ну т.е. вы сами не читали и конкретно ответить на последний вопрос не можете?
...
Рейтинг: 0 / 0
ODR:Почему глобально и в namespace надо static для функций в .h-файле, а в struct не надо?
    #38597577
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася Уткин,

Когда у функции выполняется любое из этих условий:
- указано свойство inline
- тело функции определено в теле класса
- функция является шаблоном

то компилятор помечает эту функцию в каждом объектном файле инструкцией линкеру о необходимости удалить дубликаты в разных объектных файлах.

Поэтому для этих случаев static не требуется.

ЗЫ. Не все компиляторы именно так решают проблему дубликатов. Например некоторые компиляторы поручают инстанцирование шаблонов и инлайнирование целиком линкеру, и дубликатов изначально нет.
Но суть остается прежней - для данных типов функций линкер убирает дубликаты, поэтому ODR не нарушается.
...
Рейтинг: 0 / 0
ODR:Почему глобально и в namespace надо static для функций в .h-файле, а в struct не надо?
    #38597579
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Так понятней.
Anatoly MoskovskyВася Уткин,

Когда у функции выполняется любое из этих условий:
- указано свойство inline
Ну в случае inline понятно, функции вообще как таковой не создается - на этапе компиляции код просто "копипастится" в места вызова функции.

Anatoly Moskovsky- тело функции определено в теле класса
- функция является шаблоном

то компилятор помечает эту функцию в каждом объектном файле инструкцией линкеру о необходимости удалить дубликаты в разных объектных файлах.

Поэтому для этих случаев static не требуется.
А эти "инструкции линкеру о необходимости удалить дубликаты в разных объектных файлах" - это не инструкции идентичные static или чем они от static отличаются?

Anatoly MoskovskyЗЫ. Не все компиляторы именно так решают проблему дубликатов. Например некоторые компиляторы поручают инстанцирование шаблонов и инлайнирование целиком линкеру, и дубликатов изначально нет.
Но суть остается прежней - для данных типов функций линкер убирает дубликаты, поэтому ODR не нарушается.
А например какие компиляторы?
...
Рейтинг: 0 / 0
ODR:Почему глобально и в namespace надо static для функций в .h-файле, а в struct не надо?
    #38597582
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася УткинНу в случае inline понятно, функции вообще как таковой не создается - на этапе компиляции код просто "копипастится" в места вызова функции.
Речь шла про случай когда inline игнорируется, и функция не инлайнится. В этом случае дубликаты тоже удаляются.


Вася УткинА эти "инструкции линкеру о необходимости удалить дубликаты в разных объектных файлах" - это не инструкции идентичные static или чем они от static отличаются?
static - это internal linkage. Т.е. имя не видно из других модулей. Соответственно в каждом модуле есть дубликат. Этим и отличается.
Вася УткинА например какие компиляторы?
Не помню, давно читал гдето. MSVC вроде умеет линк-тайм генерацию, но как это применимо к инстанцированию шаблонов не знаю.
...
Рейтинг: 0 / 0
ODR:Почему глобально и в namespace надо static для функций в .h-файле, а в struct не надо?
    #38597584
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyВася УткинА эти "инструкции линкеру о необходимости удалить дубликаты в разных объектных файлах" - это не инструкции идентичные static или чем они от static отличаются?
static - это internal linkage. Т.е. имя не видно из других модулей. Соответственно в каждом модуле есть дубликат. Этим и отличается.

А почему бы и в этих трех случаях не использовать internal linkage?
- указано свойство inline
- тело функции определено в теле класса
- функция является шаблоном

Зачем делать видимыми функции в других модулях, а затем их удалять как дубликаты, почему бы сразу не сделать невидимыми?
...
Рейтинг: 0 / 0
ODR:Почему глобально и в namespace надо static для функций в .h-файле, а в struct не надо?
    #38597589
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася УткинЗачем делать видимыми функции в других модулях, а затем их удалять как дубликаты, почему бы сразу не сделать невидимыми?
Потому что в стандарте написано что у них должен быть external linkage :)
А почему в стандарте так решили, есть наверно разные причины.
Например, предполагаю, чтобы во всех модулях у таких функций был одинаковый адрес.
...
Рейтинг: 0 / 0
ODR:Почему глобально и в namespace надо static для функций в .h-файле, а в struct не надо?
    #38597590
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Или например вы делаете синглтон
Код: plaintext
1.
2.
3.
4.
5.
inline Obj* get_obj()
{
  static Obj* o = new Obj();
  return o;
}



Если у вас будет internal linkage то вместо синглтона будут несколько экземпляров в каждом модуле.

Чтобы программист не задумывался об этих неприятных мелочах для функций применяется external linkage, если не указано явно обратное.
...
Рейтинг: 0 / 0
ODR:Почему глобально и в namespace надо static для функций в .h-файле, а в struct не надо?
    #38597594
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
ODR:Почему глобально и в namespace надо static для функций в .h-файле, а в struct не надо?
    #38607804
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyПро это http://www.glenmccl.com/ansi_015.htm
Спасибо, интересно. А кстати, может ли за-inline-иться функция из другого объектного файла, т.е. может ли в текущей единице трансляции встроиться функция, которая объявлена, как extern inline, но в другой единице трансляции?

авторHowever, at the most recent standards meeting in Stockholm in July, a further change was made to make external linkage the default for non-member inline functions. (The immediate motivation for this change was a need of the new template compilation model that was adopted at the same meeting; but more generally it was felt that changing the default was an idea whose time had come, and the change was approved unanimously in both ANSI and ISO).

Здесь имеется ввиду приняли extern по умолчания для inline из-за введения template (шаблонов)?
...
Рейтинг: 0 / 0
ODR:Почему глобально и в namespace надо static для функций в .h-файле, а в struct не надо?
    #38607878
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася УткинСпасибо, интересно. А кстати, может ли за-inline-иться функция из другого объектного файла, т.е. может ли в текущей единице трансляции встроиться функция, которая объявлена, как extern inline, но в другой единице трансляции?
VS имеет механизм LTCG, который позволяет инлайнить код из других единиц трансляции при связывании.
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / ODR:Почему глобально и в namespace надо static для функций в .h-файле, а в struct не надо?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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