HLFX.Ru Forum Страницы (13): « Первая ... « 8 9 10 11 [12] 13 »
Показать все 188 сообщений этой темы на одной странице

HLFX.Ru Forum (https://hlfx.ru/forum/index.php)
- Флуд (https://hlfx.ru/forum/forumdisplay.php?forumid=11)
-- Заметки на полях (https://hlfx.ru/forum/showthread.php?threadid=5815)


Отправлено XaeroX 06-08-2024 в 23:20:

Цитата:
Дядя Миша писал:
Как вы знаете, можно инициализировать переменные, объявленные в глобальном пространстве и переменные, объявленные внутри функции, а вот переменные-члены класса нельзя проинициализировать прямо там же внутри описания класса.

Ты, пожалуйста, всегда добавляй - "в шестёрке". А то звучит странно для современного плюсовика.
Цитата:
Дядя Миша писал:
Потому что никакой реальной инициализации в этом месте всё равно не происходит.

В каком "в этом" месте?
Цитата:
Дядя Миша писал:
бедные программисты, которые очень бояться перетрудится и написать несколько лишних букв в массе своей стараются не писать это слово void

Они не пишут его потому, что оно избыточно, и зашумляет текст.
Ты небось тоже не пишешь для каждого объявления инта - signed int.
Цитата:
Дядя Миша писал:
Нет, если серъезно, мне кажется что так красивее выглядит, поэтому и писал.

Ну это красота уровня public static final void.
Цитата:
Дядя Миша писал:
Это вам не Раст, который анализирует исходник целиком.

Это как?
Цитата:
Дядя Миша писал:
int foo( 5 ); // direct member initialization

А вот так у тебя можно?
C++ Source Code:
class CObject {
  int i = foo(5);  // function call
};

__________________

xaerox on Vivino


Отправлено Дядя Миша 07-08-2024 в 07:02:

Цитата:
XaeroX писал:
Ты, пожалуйста, всегда добавляй - "в шестёрке". А то звучит странно для современного плюсовика.

До 11-й версии, если быть точным.

Цитата:
XaeroX писал:
В каком "в этом" месте?

В месте объявления.

Цитата:
XaeroX писал:
Они не пишут его потому, что оно избыточно, и зашумляет текст.

Глупазте. Четыре буквы текст зашумить не могут. Текст зашумляют бесконечные обращения к STL, вызов лямбд и прочая аналогичная пакость, которой болеет современный С++.

Цитата:
XaeroX писал:
Это как?

А хрен его знает. Он же сперва парсит сорцы, а потом минут 20 думает о вечном.

Цитата:
XaeroX писал:
А вот так у тебя можно?

А что такое foo в данном контексте?

Добавлено 07-08-2024 в 10:02:

Добавил также инициализацию через = поскольку это поддерживается при инициализации объектов на стеке и в куче, следовательно логично поддержать это и здесь.
C++ Source Code:
1
class CObject
2
{
3
  vec3	origin( 10.0f, 20.0f, 30.0f );	// direct member initialization
4
  vec3	angles( 30.0f, 20.0f, 10.0f );	// direct member initialization
5
  vec3	scale = 1;				// initialization by default
6
 
7
  vec3	pool[10] = 0;
8
  vec3	test[10]( 0.0f, 1.0f, 0.0f );
9
public:
10
  int	foo = 5;				// direct member initialization
11
};

Но обратите внимание, конструкция вот такого вида
C++ Source Code:
vec3	scale = vec3( 1 );

не поддерживается, т.к. это не константное выражение. Члены класса можно инициализировать только константами.
В дальнейшем надо будет так же сделать инициализацию ссылок членов класса, поскольку они фактически были невозможными в старых версиях С++. Но я так и не смог придумать для чего подобное может понадобиться. Разве что представить ссылку в виде константного свойства только для чтения. Но в Шоте есть полноценные свойства. Так что пока не горит. Но для консистентности, разумеется надо будет потом сделать.

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'


Отправлено XaeroX 08-08-2024 в 02:48:

Цитата:
Дядя Миша писал:
Текст зашумляют бесконечные обращения к STL, вызов лямбд и прочая аналогичная пакость, которой болеет современный С++.

Ну вообще идея STL-алгоритмов как раз повысить читабельность. Вместо цикла - понятное название, скажем std::find_if.
Цитата:
Дядя Миша писал:
А что такое foo в данном контексте?

Ну скажем, глобальная функция. В плюсах можно написать вот так:
C++ Source Code:
1
int foo(int i) {
2
  return sqrt(i);
3
}
4
 
5
struct C {
6
  int i = foo(25);
7
};

И вот так можно написать - для эстетов:
C++ Source Code:
1
int foo(int i) {
2
  return sqrt(i);
3
}
4
 
5
struct C {
6
  int i = [](){ return foo(25); }();
7
};

А можно и вот так!
C++ Source Code:
1
int foo(int i) {
2
  return sqrt(i);
3
}
4
 
5
struct C {
6
  int i = 2*[](){ return foo(25); }();
7
};

Понятно, что вместо явно прописанных цифровых констант могут быть конст-переменные или макросы.
А могут быть другие функции. Вообще любые функции, они будут выполняться в момент создания экземпляра класса.

__________________

xaerox on Vivino


Отправлено Дядя Миша 08-08-2024 в 06:01:

Цитата:
XaeroX писал:
скажем std::find_if.

Вот эти std:: зашумляют текст куда сильнее чем void. Как раз из-за двоеточий.

Цитата:
XaeroX писал:
Ну скажем, глобальная функция.

Так скажем, или глобальная? Я такого не делал, только инициализацию константными значениями. Но если мне такое понадобится, можно будет подумать.

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'


Отправлено XaeroX 08-08-2024 в 12:44:

Цитата:
Дядя Миша писал:
Но если мне такое понадобится, можно будет подумать.

Ну а если остальным такое понадобится, они просто возьмут С++. Логично.

__________________

xaerox on Vivino


Отправлено Дядя Миша 08-08-2024 в 13:14:

Цитата:
XaeroX писал:
Ну а если остальным такое понадобится, они просто возьмут С++. Логично.

В шестёрке так допустим было нельзя, но все работали в ней и никто не жужжжал!

Впрочем, учитывая архитектуру Шота, я могу ещё много интересных конструкций добавить в язык, чисто в рамках компилятора. Интерпретатор останется прежним и совместимость тоже не пострадает.

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'


Отправлено Дядя Миша 30-08-2024 в 12:19:

Кстати. Порядок инициализации глобальных конструкторов в cinit определён порядком исходных файлов, подаваемых на вход компиляции.
А порядок исходных файлов в свою очередь нарушен быть не может, т.к. компилятор автоматически сортирует их по алфавиту. Таким образом, если вы делаете какой-то надкласс, который призван следить за всеми остальными, ну например отладчик памяти, файл с объявлением экземпляра должен называться таким образом, чтобы гарантировано стать первым в списке компиляции. Ну например с восклицательного знака.
Но в шестёрке есть баг, что если добавить файл и сразу же начать компиляцию, то он будет добавлен в список самым последним.
Помогает выгрузка - загрузка проекта. Но возможно что этот баг так до сих пор не исправили и в новых студиях.
В Шоте авто-сортировки по именам нету, можно вручную задавать приоритеты. Но да, принцип тот же.
Кстати этот момент технично обходится во всех учебниках по С++ и возможно вообще не подлежит стандартизации.

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'


Отправлено Дядя Миша 10-09-2024 в 15:22:

Добавил новый compile-time оператор is_polymorphic. Это аналог std::is_polymorphic, позволяет получить ответ, есть ли в классе виртуальные методы. Пригодится.

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'


Отправлено Дядя Миша 12-09-2024 в 10:08:

Интересное дело. НИГДЕ не удалось нагуглить даже малейших следов описания приоритета неявного приведения операторов преобразования типов. Эта тема, то ли считается неважной, то ли про нее тоже никто не знает. Приведу пример:

C++ Source Code:
1
class CVarFloat
2
{
3
  float	value;
4
public:
5
  CVarFloat() : value(0.0f) {}
6
  CVarFloat( float in ) : value(in) {}
7
  operator float() const { return value; }
8
};

Вот у нас есть такой симпатичный прокси-класс. И поскольку у него есть оператор приведения типа к float мы естественно хотим его умножить.
C++ Source Code:
1
CVarFloat	a( 2.0f );
2
CVarFloat	b( 2.0f );
3
 
4
float fc = a * b;
5
int ic = a * b;
6
bool bc = a * b;
7
Msg( "%g %d %d\n", fc, ic, bc );

Это нам выдаст 4 4 1. Почему в случае с bool получился 1 нас сейчас не особо интерисует, т.к. это всё равно невалидная операция. Явно не то, чтобы мы хотели получить. Интересно другое. Каким образом компилятор дотумкал во что ему надо преобразовывать типы? Но мы пойдем дальше.
Добавим явное преобразование в int. Вот так
C++ Source Code:
1
class CVarFloat
2
{
3
  float	value;
4
public:
5
  CVarFloat() : value(0.0f) {}
6
  CVarFloat( float in ) : value(in) {}
7
  operator float() const { return value; }
8
  operator int() const { return value; }
9
};

В результате получим три ошибки
C++ Source Code:
error C2593: 'operator *' is ambiguous

Но почему, собственно? Он теперь не может выбрать какой использовать? Значит на тип операнда в который пишется результат он не смотрит. Хорошо. Но и на тип второго операнда он смотреть не может. Это бы имело значение, если бы A был float или B был float. Однако у нас тут два класса, которые потенциально можно привести к какому-то простому типу.
Очевидно, раз компилятор НЕ МОЖЕТ полагаться на типы ABC, он выполняет приведение соответствуясь с некоторыми внутренними жестко установленными правилами. Ну а как ещё-то? То есть скажем в первую очередь пытается привести ко float, затем к int. Ну это навскидку. Я этих правил не знаю. И НАГУГЛИТЬ ИХ НИГДЕ НЕ УДАЛОСЬ АБСОЛЮТНО.
Никто про это даже не вспоминает. А возможно и не знает даже или просто не задумывается как работает эта магия.

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'


Отправлено Unit 12-09-2024 в 16:05:

Цитата:
Дядя Миша писал:
Но почему, собственно? Он теперь не может выбрать какой использовать?


When two or more user-defined conversions that perform the same conversion are available at a conversion site, the conversion is said to be ambiguous. Such ambiguities are an error because the compiler can't determine which one of the available conversions it should choose

Моё мнение - весь этот сахар с операторами преобразования приводит к ошибкам, которые даже заметить порой сложно.
Лучше использовать каст методы с "говорящими" именами, toString(), toFloat() и т.д.


Отправлено Дядя Миша 12-09-2024 в 21:01:

Ну я уже понял, что для выражения C = A x B где x арифметическое действие, нет никакой возможности выбрать правильный тип для преобразования. C может отсутствовать вообще, если выражение передается аргументом в функцию, финальный тип которого в свою очередь учитывает дедуктор перегрузки функций. Так что видимо да - только выбор из одного оператора. Сделал аналогично.

Добавлено 13-09-2024 в 00:01:

При этом разумеется кол-во операторов приведения типов по-прежнему может быть каким угодно, но в спорных случаях требуется явный каст.

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'


Отправлено PRoSToTeM@ 12-09-2024 в 22:07:

Цитата:
Дядя Миша писал:
Интересное дело. НИГДЕ не удалось нагуглить даже малейших следов описания приоритета неявного приведения операторов преобразования типов. Эта тема, то ли считается неважной, то ли про нее тоже никто не знает.

https://en.cppreference.com/w/cpp/l...icit_conversion

Цитата:
Дядя Миша писал:
Приведу пример:

C++ Source Code:
1
class CVarFloat
2
{
3
  float	value;
4
public:
5
  CVarFloat() : value(0.0f) {}
6
  CVarFloat( float in ) : value(in) {}
7
  operator float() const { return value; }
8
};

Вот у нас есть такой симпатичный прокси-класс.

Добавим пару функций:
C++ Source Code:
1
auto bar(float lhs, float rhs) {
2
  return lhs * rhs;
3
}
4
 
5
auto bar(int lhs, int rhs) {
6
  return lhs * rhs;
7
}

В данном случае в следующих двух выражениях выполняется одна и та же логика с implicit casts:
C++ Source Code:
a * b // calls operator*(float, float)
bar(a, b) // calls bar(float, float)

Соответственно, если добавить в класс operator int, то будет ambiguous в обоих случаях. Т.е. использование операторов ничем не отличается от вызова функций (во многих ситуациях).

Можно потыкаться на compiler-explorer.


Отправлено Дядя Миша 18-09-2024 в 07:15:

Большое дело сделал - отложенную кодогенерацию шаблонных методов.
Теперь если какие-то функции из шаблонного класса используют операторы\методы, которых нет в классе, представленном в качестве шаблонного аргумента, то компилятор на это не ругается при условии, что эти функции нигде в коде не были вызваны, ну потому что код генерируется только для реально использованных функций.

Вот простой пример: в шаблонном классе динамического контейнера есть метод find, который сравнивает объект из своего аргумента с объектами, находящимися в массиве через оператор ==. Если шаблон сразу же инстанцирует все свои функции, то от каждого такого класса он будет требовать наличие пользовательского оператора ==. Это весьма неудобно, если учесть что пользователь сам метод find может и вовсе не вызывать.
Теперь этой проблемы нет. Ну а сам принцип хранения исходного кода в структуре объявленных функций наталкивает меня на мысль, что вместо того чтобы явным образом эмитить опкоды (как я это делаю сейчас для тех функций, которые генерирует компилятор) можно просто генерировать исходный текст этих функций. Это ведь намного проще и удобнее - думать не надо средствами компилятора. А компилятор их потом сам распарсит, как будто бы это настоящие функции. Весьма вероятно что всякие копи-конструкторы, которые генерирует компилятор, я именно так и реализую - генерацией исходного кода, а не серией вызовов EmitAddress, EmitObjectCall и прочего.

Добавлено 18-09-2024 в 10:15:

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

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'


Отправлено Дядя Миша 30-10-2024 в 09:38:

Объявил элемент двухсвязного списка, а его же по дефолту надо инициализировать самим собой, ну я и написал:

C++ Source Code:
1
struct link_t
2
{
3
  link_t	*next;
4
  link_t	*prev;
5
 
6
  link_t() : next(this), prev(this) {}
7
};

И моментально получил варнинг
warning C4355: 'this' : used in base member initializer list

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'


Отправлено FiEctro 30-10-2024 в 11:22:

Цитата:
Предупреждение C4355: 'this' : used in base member initializer list возникает потому, что вы используете указатель this в списке инициализации членов до того, как объект полностью создан. Это может привести к неопределенному поведению, так как объект еще не находится в корректном состоянии.

В вашем случае, если вы хотите инициализировать элемент двусвязного списка самим собой, вам нужно сделать это после того, как объект будет полностью создан. Вы можете использовать конструктор по умолчанию для инициализации указателей next и prev в nullptr, а затем в теле конструктора установить их на this.


C++ Source Code:
1
struct link_t
2
{
3
  link_t* next;
4
  link_t* prev;
5
 
6
  link_t() : next(nullptr), prev(nullptr)
7
  {
8
    next = this;
9
    prev = this;
10
  }
11
};

__________________
У котёнка мокрый нос и гладенькая шерсть, у него забавный хвост и быстрых лапок шесть. Две задних, две средних и две передних лапы, такая многоножка получилася у папы.
Он ученый — папа мой — зверушек изучает, гуляет по помойкам, ловит крыс и чаек. Две крысы белокрылые и чайки две унылые покрытые пупырчатою кожей лягушат без пёрышек тоскуют и ускакать спешат.
А ещё есть муравей большой размером с гуся он пугает всех зверей, и я его боюся, когда он ковыляет на лапках на своих.
И в двери ударяет, и начинает стих: Я — муравей, воды налей! Не меньше ведра, напиться мне пора!


Временная зона GMT. Текущее время 03:39. Страницы (13): « Первая ... « 8 9 10 11 [12] 13 »
Показать все 188 сообщений этой темы на одной странице

На основе vBulletin версии 2.3.0
Авторское право © Jelsoft Enterprises Limited 2000 - 2002.
Дизайн и программирование: Crystice Softworks © 2005 - 2024