Здравствуйте, Евгений Музыченко, Вы писали:
R>>то, что делаешь методом научного тыка, ты делаешь на свой страх и риск.
ЕМ>Да в программировании для открытых систем (а тут большинство только для таких и делает), внезапно, почти все делается на свой страх и риск.
Большинство... Почти все... Какой съезд партии тебя делегировал, чтоб за всех расписаться?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Здравствуйте, rg45, Вы писали:
R>>то, что делаешь методом научного тыка, ты делаешь на свой страх и риск.
ЕМ>Да в программировании для открытых систем (а тут большинство только для таких и делает), внезапно, почти все делается на свой страх и риск.
Хм, почему?
Открытые системы — не значит, что нет стандартов.
Здравствуйте, netch80, Вы писали:
N>Открытые системы — не значит, что нет стандартов.
Во-первых, их достаточно мало на фоне общего разнообразия. Во-вторых, их соблюдение весьма опционально — тот же POSIX не в состоянии заставить каждого сисадмина поддерживать свою систему в полном соответствии со стандартом. В-третьих, даже при полном соблюдении всех стандартов остается вероятность аппаратных ошибок и ошибок окружения, которая в среднестатистической конфигурации достаточно велика. Поэтому смысл снижать вероятность неправильного поведения программы ниже некоторого разумного порога есть только для небольшого класса сверхнадежных программ, работающих только в сверхнадежных же системах.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Во-первых, их достаточно мало на фоне общего разнообразия.
Так никто вроде и не говорил, что их много. К чему это вообще?
ЕМ>Во-вторых, их соблюдение весьма опционально — тот же POSIX не в состоянии заставить каждого сисадмина поддерживать свою систему в полном соответствии со стандартом.
Ну разумеется, стандарты не могут никого заставить себя соблюдать.
ЕМ>В-третьих, даже при полном соблюдении всех стандартов остается вероятность аппаратных ошибок и ошибок окружения, которая в среднестатистической конфигурации достаточно велика. Поэтому смысл снижать вероятность неправильного поведения программы ниже некоторого разумного порога есть только для небольшого класса сверхнадежных программ, работающих только в сверхнадежных же системах.
Детский сад какой-то. "Зачем чистить зубы, если всё равно умрёшь".
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Детский сад — это регулярно посматривать вверх на случай, если с пролетающего самолета будет что-нибудь падать.
Ты сам-то понял свою метафору?
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Говоря о "гарантиях", полезно понимать, что это отнюдь не следствия законов природы, а всего лишь утверждения, обещания. Они соблюдаются, пока их невыгодно нарушать. Для каждой гарантии есть вероятность ее нарушения, которую следует соотносить с вероятностями других событий, которые могут повлиять на работу программы.
Вот ты странный. В том-то и дело, что никто тебе ничего не обещает. Но ты, тем не менее, рассчитываешь на то, чего тебе никто не обещал. Так получается.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, Chorkov, Вы писали:
C>Проблема будет при наследовании не классов, содержащих виртуальные функции, от классов не содержащих виртуальных функций, с виртуальным наследованием,... C>https://gcc.godbolt.org/z/vnT9vnasM
Так а в чём тут проблема? Да, здесь база с ненулевым смещением.
Тот же эффект можно достичь на обычном множественном наследовании.
struct AB { int a, b; };
struct V { void* vfptr; };
struct C : V, AB { int c; };
static_assert(offsetof(AB, b) == sizeof(int));
static_assert(offsetof(C, b) == sizeof(Z) + offsetof(AB, b));
Здравствуйте, sergii.p, Вы писали:
SP>offsetof использует хак с разыменовыванием нулевого указателя. И получается на виртуальном наследовании это может не работать. Можно попробовать самому реализовать что-то подобное на уже существующем объекте
Для этого этот объект надо создать. Как в данном примере.
А у него конструктор не тривиальный, и хорошо, если у него вообще есть дефолтный конструктор, чтоб создать эталонный объект, который не жалко измерять.
Здравствуйте, kov_serg, Вы писали:
R>>Есть ещё один минус в таком подходе — полученное значение уже не будет compile-time.
_>https://godbolt.org/z/8847Mjd7b
Ну и где тут "объект уже есть", о чём говорилось выше? Ты же просто предлагаешь альтернативную реализацию offsetof, не требующую наличия объекта. Просто вместо UB от использования нулевого указателя, у тебя UB от неправомерного использования reinterpret_cast, вот и всё. Так ещё и тонны кода навертел.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, kov_serg, Вы писали:
R>>>Есть ещё один минус в таком подходе — полученное значение уже не будет compile-time.
_>>https://godbolt.org/z/8847Mjd7b
R>Ну и где тут "объект уже есть", о чём говорилось выше? Ты же просто предлагаешь альтернативную реализацию offsetof, не требующую наличия объекта. Просто вместо UB от использования нулевого указателя, у тебя UB от неправомерного использования reinterpret_cast, вот и всё. Так ещё и тонны кода навертел.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, Chorkov, Вы писали:
C>>Проблема будет при наследовании не классов, содержащих виртуальные функции, от классов не содержащих виртуальных функций, с виртуальным наследованием,... C>>https://gcc.godbolt.org/z/vnT9vnasM
К>Так а в чём тут проблема? Да, здесь база с ненулевым смещением. К>Тот же эффект можно достичь на обычном множественном наследовании. К>
К>struct AB { int a, b; };
К>struct V { void* vfptr; };
К>struct C : V, AB { int c; };
К>static_assert(offsetof(AB, b) == sizeof(int));
К>static_assert(offsetof(C, b) == sizeof(Z) + offsetof(AB, b));
К>
С множественным наследованием, пользователю очевидно что указатель на экземпляр класса-наследника не будет численно совпадать с указателями на каждый из базовых классов.
В случае с внезапно появившейся виртуальной функцией не очевидно, что база с ненулевым смещением. (Нужно внимательно просмотреть все тело класса, чтобы заметить virtual.)
При этом смещение, которое суть число — не содержит информации от начала экземпляра какого класса оно отсчитано.
Поэтому, либо всегда отсчитывать смещения от одной базы (но offsetof не позволяет отсчитать смещение члена наследника от начала базового класса), либо использовать указатели на члены класса, которые содержат в своем типе информацию о точке отсчета.
Мало того что из стандартной библиотеки он предварительно уматерит (warning: ‘offsetof’ within non-standard-layout type ‘D’ is conditionally-supported [-Winvalid-offsetof]).
И как его в шаблонах использовать такой стандартный? Например: