- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
// https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
// The Curiously Recurring Template Pattern (CRTP)
template<class T>
class Base
{
// methods within Base can use template to access members of Derived
};
class Derived : public Base<Derived>
{
// ...
};
> The Microsoft Implementation of CRTP in Active Template Library (ATL) was independently discovered, also in 1995 by Jan Falkin who accidentally derived a base class from a derived class. Christian Beaumont, first saw Jan's code and initially thought it couldn't possibly compile in the Microsoft compiler available at the time. Following this revelation that it did indeed work, Christian based the entire ATL and Windows Template Library (WTL) design on this mistake.
А какая ошибка по-вашему положена в основу всего дизайна языка C++?
Может суть языка C++ это использование (открытие) каких-то ебанутых багофич, по поводу которых даже возникают сомнение, соберется ли вообще это говно, или нет?
"It was not any particular function, but the number of them. Bjarne is personally responsible for reducing the number of components in STL by a factor of two. He was trying to make it as small as possible to placate the opposition. "
http://www.stlport.org/resources/StepanovUSA.html
В с++17 добавили приснопамятные функции Бесселя.
Главная проблема дизайна с++ - это желание угодить всем, что вытекает в очень противоречивые и политически ангажированные решения по поводу добавления новых фич.
https://www.npmjs.com/package/bessel
1) JS-like: в стандартной библиотеке нет ровным счётом нихуя. Однако присутствует мощный и крайне простой пакетный менеджер с большим архивом библиотек, для использования которого достаточно просто написать «import».
2) Python-like: в стандартную либу напихано огромное количество модулей на любые случаи жизни; сторонние библиотеки нужны гораздо реже и только для сильно специфических (по сравнению с предыдущим пунктом) задач.
3) ГовноC++-like: в стандартной либе нет почти нихуя (а то, что есть — неюзабельное говно). При этом пакетного менеджера тоже нет и не предвидится, а установка сторонних библиотек — ёбанный ад.
4) Вроде пакетный менеджер есть, но всё сломано и нихрена не ставится (Haskell-like).
https://www-users.cs.york.ac.uk/susan/joke/cpp.htm
s: https://habr.com/ru/company/jugru/blog/438866/
DLL/so чем не поздний линкер?
Запросто. *a является синонимом a[0]. Можно явно писать [0] вместо звёздочки.
И даже так:
а в другом к нолю прибавил s
от перестановки мест слагаемых...
Не по этой ли причине некоторые боятся звёздочки в сишке?
Играю роль, такую роль,
И в этой роли, безусловно, я массив.
Для кокококонсистентности надо было вместо структур тоже сделать указатели.
А теперь переставь поля местами.
Зазоров не будет, если size_t совпадает по размеру с паддингом (обычно достаточно кратности машинному слову) или если указаны директивы для упаковки структуры (#pragma, __attribute__ –— вот это всё).
Что же касается паддинга в самом конце, то обычно такие структуры применяют к уже выделенной памяти, поэтому на sizeof нам плевать.
Но вообще да, какое-то чувство незавершённости остаётся.
P.P.S. Торможу, есть же FileNameLength.
Запиливаешь шаблонный итератор и хоть няшным с++11 for'ом по этой хуйне бегай.
Это к слову о том, почему я люблю кресты для low-level.
Верно. Есть даже такой прикол:
Так что в некоторых контекстах массивы действительно есть.
Но вот конструкции вроде [42]petuh, petuh+42 (и для «petuh», объявленного как указатель, и для «petuh», объявленного как массив) и отсутствие разделения указателя на массив и указателя на скаляр сбивают с толку новичков.
Конструкции *petuh и petuh[0] работают одинаково, причём всё в силе как для char *petuh, так и для char petuh[42].
Но ведь это не строка, а просто сахарок для массива из чаров с нулём в конце. И это тоже важный момент для понимания сишки.
Выбрось свой древний конпелятор. Он протух.
З.Ы. Хм, странно, в сишном режиме даже ворнингов нету на эту херню...
А как поменять ключ секции? Линкером?
Как поменять страницу я понимаю, хотя это и не оч секурно
Линкеру можно сказать: "навесь на эту секцию вот такие атрибуты".
Загрузчик мапает секции так, как ему сказал линкер.
Блин, посмотри в доке от соответствующего копулятора. Я флешку паяю, некогда гуглить.
Можешь готовую секцию взять (и подкрутить ей атрибуты при желании). Можешь в новую высрать.
> у прыщей
Ну и терминология!
У «gcc» ты можешь указать имя секции, в которую совать переменную. А вот секцию создаёт линкер. Вероятно, ему нужно скормить объектный файл, в котором эта секция уже создана ассемблером.
В сишные и крестовые стандарты добавляют всякую всячину, но не стандартизировали прагмы.
В общем, нужно посмотреть две вещи:
1. Какие прагмы есть в разных компиляторах.
2. Какие секции поддерживает загрузчик ОС.
*****
Виндовому загрузчику PE-файлов, если не ошибаюсь, на количество и названия секций насрать. Он смотрит атрибуты каждой секции. Ты можешь, например, создать секцию PETUH с атрибутами R-X и секцию KUROCHKA с атрибутами RW.
*****
В «a.out» количество секций фиксировано: есть .text (r-x, инициализированная), .data (rw, инициализированная), .bss (rw, неинициализированная) с заранее известными всем атрибутами. То есть даже для кокококонстант секции нет.
Если важно защитить константы от исполнения, их кладут в секцию .data (насрав на отсутствие защиты от записи). Если важно защитить константы от записи, их кладут в секцию .text (насрав на отсутствие защиты от исполнения).
*****
В «ELF», как и в «PE», можно создать 100500 секций с произвольными атрибутами.
У «XCOFF» количество секций произвольно, однако, произвольные атрибуты выставлять нельзя, можно выбирать только стандартные шаблоны (секция типа «.text», секция типа «.data») и т. п.
У «PEF» («Mac OS Classic») такая же ерунда, однако, есть секция для констант, а у «XCOFF» я её не нашёл.
У «Mach-O» («Mac OS X») похоже, что тоже стандартный набор шаблонов, причём шаблоны привязаны к названию. Шаблонов стало больше, но свои атрибуты секции создавать нельзя. Нужно искать секцию с подходящим названием.
У «NE» (16-битные приложения «Windows» и «OS/2») можно создавать произвольное количество секций с произвольными атрибутами (разрешения на чтение, запись, выполнение выставляются отдельно, как и у «PE» и «ELF»).
1. Можно создать секцию с произвольными атрибутами: «ELF», «Windows», «OS/2».
2. Можно создать секцию, но из заранее заготовленных шаблонов: системы типа «Макоси».
3. Можно только выбирать из готовых секций: «a.out».
В x64 они дополнительно защищены от исполнения. В x32 без DEP они защищены только от записи.
З.Ы. Хотя на тех же stm'ках можно снять блокировку с флеша и менять единички на нолики...
Вы про 42[petuh]?
Кстати, зачем эта питушня нужна? Не могу придумать ситуации, где бы она понадобилась. (Реальной ситуации, а не заседания клуба задротов или "креативных" вопросов на собеседованиях)
"оффсет петуха поюс 42"
или
"42 плюс оффсет питуха"
и все
не то чтобы ее как-то специально делали
почему оно тогда во всех компиляторах работает?
"оффсет петуха плюс 42 на размер элемента петуха"
или
"42 плюс оффсет питуха на размер элемента 42"
А это уже не симметричная питушня.
Для других комбинаций типов слагаемых аналогичной перегрузки нет (есть только сложение скаляров), поэтому к неоднозначности это не приводит.
Сравним, как сделали в «Турбо Паскале», «Delphi» и в более поздних проектах вроде «FPC».
1. Если в функцию передаёшь массив, то пушится не сам массив, а указатель на его копию в стеке («копирующий конструктор»; если передаёшь литерал, то он где-нибудь создаётся и тоже передаётся указатель). Но точно так же он поступает и с другими огромными данными вроде структур.
Если формальный параметр имеет атрибут const, то копирование не производится, передаётся только указатель на оригинал, но при этом статический анализатор проверяет, что функция не изменяет данные по этому указателю. Если формальный параметр имеет атрибут var, то ещё проще: ни копирования, ни проверки. Фактически это концепция ссылки.
Если тип параметра является статическим массивом, то размер передавать не нужно, он известен на этапе компиляции.
Есть более сложные сущности: открытые массивы (array of integer, например), динамические массивы и array of const. В этом случае после указателя на массив компилятор пушит ещё его размер.
2. Если же вызываемая функция должна вернуть массив или структуру, то он выделяет место в стеке под результат и самым последним аргументом передаёт указатель на это место. Т. е. результат живёт там же, где живут локальные переменные вызывающего кода (никакой возни с ручным выделением/освобождением).
Да, эти два приёма по сути являются хаками. Однако, структуры и массивы обрабатываются единообразно.