class Example
{
private:
uint8_t * someSelfAliasableMember;
int a;
int b;
int c;
public:
Example() : someSelfAliasableMember(new uint8_t[100]) {}
void doSomething() __restrict
{
for (int32_t i = 0; i < 10; ++i)
{
someSelfAliasableMember[i] = i;
}
}
};
Тут проблема не в том, что член класса char*, а в том, что запись идет в char*, и из-за strict aliasing правил - это может быть запись куда угодно, в том числе в &this. Кешировать пришлось бы любой член структуры, любого типа.
Эту же проблему можно воспроизвести в меньшем масштабе, если у вас в цикле есть запись в int* и чтение какой-то другой не меняющейся int переменной. Особенно, когда переменная в куче и указатель пришел в параметре функции.
static void InterpolateSnapshot_Hermite_WithExtrapolation( float t,
float step_size,
float extrapolation,
const __restrict CubeState * a,
const __restrict CubeState * b,
__restrict view::ObjectUpdate * output )
Если нет необходимости в подобной локальной переменной, то не нужно "кэшировать".
На уровне ассемблера все обращения к памяти происходят через регистры, так что в любом случае адрес из указателя будет записан в регистр и этот регистр будет индексироваться.
Частично это можно решить кешированием, можно попробовать поменять типы кое где.
void method () __restrict {}
) не является эквивалентным кэшированию в локлаьную переменную ? за исключением того, что ничего кэшировать не придётся, так как компилятор уже будет знать, что переменная ни с чем в рамках данного метода не overlapp'ится" в памяти ?
floppa322, Если это статический метод Example/ExtremelyHeavyObjectBuilder/ExtremelyHeavyObject, то можете так делать.
В случае статического метода ExtremelyHeavyObjectBuilder/ExtremelyHeavyObject требуется указать класс, т.е. будет что-то вроде ExtremelyHeavyObjectBuilder::createObj().
Так же createObj может быть и свободной функцией.
То что вы предлагаете (объявление builder и прочее), можно вынести в вышестоящий код, который будет создавать экземпляр Example, и в конструктор Example передавать результат builder.build(), в списке инициализации просто передадите параметр конструктора Example в параметр конструктора obj.
Example()
: obj(createObj())
{}
Сегодня использование англиканизмов в профессиональной среде трактуется как признак низкой квалификации. Квалифицированный специалист способен объясняться исключительно терминами родного языка.
Индирект - косвенность. Statement'ы - выражения.
Когда человек сыпет тяжелыми на слух англиканизмами, его становится тяжело понять. Это заставляет слушателя напрягаться и нервничать. А это уже ведет к обострению общения и может быть воспринято как неуважение.
По поводу стиля кода. Оформление, откровенно говоря, рваное. Это точно так же заставляет задумываться, вчитываться и искать. Думаю, поэтому у тебя пока еще нет ответов. Лично мне потребовалось 4 раза перечитать код чтобы увидеть в нем инициализатор. Первые три раза я видел просто неправильный синтаксис. В широкой практике инициализатор оформляется примерно схожим образом: блоком по строкам. Посмотри пример.
Example():
и до тела конструктора - вообще псевдо код, предположительный синтаксис, который бы подошёл. Наверное, нужно было это указать
floppa322 , шаблон класса - это, прежде всего, шаблон типа. Это еще не тип и работать с шаблоном как с типом невозможно. Шаблон всегда требуется инстанцировать, результатом инстанцирования шаблона типа всегда будет тип, у которого уже можно получить доступ к полям и функциям.
добавляя "фиктивные" шаблонные параметры как-то слишком костыльно
После инстанцирования шаблона с параметрами, статическое поле MEMBER_TO_BE_ACCESSIBLE_OUTSIDE будет принадлежать только пространству инстанцированного типа. Иными словами, для каждой уникальной комбинации аргументов шаблона MEMBER_TO_BE_ACCESSIBLE_OUTSIDE будет иметь свой уникальный адрес размещения.
Извиняюсь за глупый вопрос, но откуда у пользователя возьмётся корректный стек вызовов?
Вот эта самая Backward-cpp и ей подобные выдачу коллстека и сделают корректной. Современная инструментация отладки позволяет опознать фрагменты встроенного кода и правильно оформить коллстек для выдачи.
И на производительности конкретно установка обработчиков тоже не сказывается.
подводные камни - это возможность полной декомпиляции твоей программы по ее отладочным меткам. В наши дни эта проблема решается обрезанием отладочной информации в процессе релиза для пользователей. В результате пользователи при падении видят только отчет со стеком вызовов и все. Это действие - джентельменский минимум уважающего себя производителя ПО.
я просто не понимаю, почему __restrict по умолчанию не применяется к сигнатуре метода, делая this - константным указателем, потому как редко в коде встретишь что-то вроде this = something