Constantine
А там вообще арифметика указателей определена в этом случае?
Constantine
++ на такой указатель это не единственная гарантия про арифметику и сравнения? :)
Ivan
Я у вас хотел спросить, есть неопределенное поведение или нет? То что я сказал, не соответствует приоритету операций
Constantine
Ну
*b++
это точно UB
Constantine
результат b++ совершенно точно не указывает на int
Constantine
я не очень хорошо знаю, что там гарантируется про b++ вообще
Constantine
я даже не уверен, скажем, что b++ еще не UB :)
Олександр
Constantine
Constantine
А то я слышал, что указатели int* и char* могут иметь разный sizeof
Олександр
Цитатку со стандарта можно?)
Да ладно, серьезно? Это же еще из С идет.
Но тут UB хотя бы потому, что инкрементить можно только указатели на массив, остальное UB.
Constantine
Олександр
Олександр
Мб неправильно выразился
Constantine
Собственно говоря тут принципиальный вопрос - разрешено ли получение указателя типа end для адреса переменной? Т.е. считается ли, что типы (x[0] в T x[1]) и T x достаточно одинаковы?
Олександр
Если int pointer будет указывать на int array[10] и его инкрементнуть, то это будет эквивалентно pointer += sizeof(int)
Constantine
Олександр
Constantine
A pointer converted to an integer of sufficient size and back to the same pointer type is guaranteed to have its original value, otherwise the resulting pointer cannot be dereferenced safely (the round-trip conversion in the opposite direction is not guaranteed; the same pointer may have multiple integer representations)
Constantine
Вот такая гарантия, говорят
Олександр
Constantine
Инкремент дальше последнего элемента - НЕ UB
Constantine
Разрешен указатель на end для массива
Constantine
Например, в сравнениях типа <> есть явная оговорка об этом
Олександр
Constantine
Так дальше end
Ну тогда переформулируйте, потому что end это следующий после последнего
Constantine
Его нельзя разыменовать
Constantine
Кроме того, должны быть совершенно точно оговорки про char / unsigned char / std::byte
Constantine
У них своя атмосфера
Vitaliy ◀️TriΔng3l▶️
Vitaliy ◀️TriΔng3l▶️
Не на x86-16
Constantine
Там когда множественное наследование х3 что бывает
Max
Max
Растянули полотно) ub, не ub
Constantine
Ivan
Ох же, вроде 4 маленьких строки кода, а столько дискуссий
Constantine
Vitaliy ◀️TriΔng3l▶️
Vitaliy ◀️TriΔng3l▶️
А, это всё равно pointer -> size_t -> pointer -> size_t выйдет
Constantine
Речь о том, что pointer -> size_t может быть несколько версий
Vitaliy ◀️TriΔng3l▶️
А, ну это очевидно
Constantine
Грубо говоря, допустимо int32_t * хранить с доделиванием на 4 и рандомно заполнять младшие биты после умножения на 4 и перевода в size_t
Constantine
Поэтому size_t -> pointer -> size_t может сломаться
Max
Не совсем
std::vector v = { 0 };
v[v.size()];
Ub
Constantine
blow
А как вы достигли таково задротства в кодинге?
Max
Vitaliy ◀️TriΔng3l▶️
Это уб, то уб, поэтому бе, не буду так писать
Max
Аргументно
Constantine
А вы когда-нибудь видели код strlen?
Constantine
Слышали про capacity?
Nikita
ребят, а gtest гоняет тесты многопоточно?
Constantine
Про destructive alignment?
Constantine
Существует куча случаев, когда это не UB
Vitaliy ◀️TriΔng3l▶️
Хм, пойду у своих вызовов маллока размеры выровняю до 8 или 16
B
Max
Constantine
Max
Причем тут капасити
Nikita
меня интересует именно многопоточность
вообще говоря не совсем это интересует
если у меня несколько тестов использует один и тот же объект, безопасно ли это?
Max
Доступ к неинициализированному элементу - ub
Max
Вот вам и капасити
Constantine
Constantine
placement new делается на неинициализированной памяти
Vitaliy ◀️TriΔng3l▶️
Чтобы можно было всё, что (&7)==0, кастовать к uint64_t, а что (&15)==0 — кидать в movaps или movdqa
B
Nikita
типо struct Test {
static int a;
};
Constantine
так что допустимо вычислять lvalue reference на неинициализированную память
B
они вызываются не параллельно
Nikita
Constantine
Constantine
Свой