170 похожих чатов

Так а почему это UB, если двумерный массив лежит в

памяти линейно?
Не сдвинемся ли мы просто на следующую строку?

56 ответов

31 просмотр

потому что в стандарте так написано что это уб

Есть шанс что памяти не будет, например

Gleb-Pylypets Автор вопроса
Liber Azerate
Есть шанс что памяти не будет, например

как её там не будет, если мы создали двумерный массив?

Gleb-Pylypets Автор вопроса
P I K A
потому что в стандарте так написано что это уб

так а что именно? мы просто ссылаемся на начало массив и двигаемся сколько нам нужно?

Gleb Pylypets
как её там не будет, если мы создали двумерный мас...

А, я не посмотрел на изначальный пример. Ну, в любом случае в стандарте такая адресация запрещена

Тут начинается ОЧЕНЬ длинный спор на эту тему

Gleb-Pylypets Автор вопроса
Alexander Karaev
https://godbolt.org/z/78KWfsq7o

а что это значит? я просто с телефона

Liber Azerate
А, я не посмотрел на изначальный пример. Ну, в люб...

а если по другому написать, *(ptr + length*row_count + in_row_number), че на это скажешь?)

Gleb Pylypets
а что это значит? я просто с телефона

constexpr int f() { int a[3][3] = {}; return a[0][5]; } <source>:1:15: error: constexpr function never produces a constant expression [-Winvalid-constexpr] constexpr int f() { ^ <source>:3:12: note: cannot refer to element 5 of array of 3 elements in a constant expression return a[0][5];

Gleb-Pylypets Автор вопроса
Ofee Oficsu
Тут начинается ОЧЕНЬ длинный спор на эту тему

так а если одним словом, то итог какой? я просто ответил, что UB, но не уверен

Gleb-Pylypets Автор вопроса
Alexander Karaev
constexpr int f() { int a[3][3] = {}; retu...

я просто не понимаю - и что это значит?

Kelbon
а если по другому написать, *(ptr + length*row_cou...

Скажу, что валидно адресоваться только в рамках строчек по ptr

Gleb Pylypets
я просто не понимаю - и что это значит?

Это значит, что в компайл-тайме нет уб Только ошибки компиляции

Gleb-Pylypets Автор вопроса
Liber Azerate
Скажу, что валидно адресоваться только в рамках ст...

вот поэтому и надо знать, есть ли в стандарте си где нибудь "a[n][m] всегда реализуется как последовательная память ..."

Kelbon
вот поэтому и надо знать, есть ли в стандарте си г...

При чём тут это? Это и в стандарте С++ есть

Danya🔥
У нас тут С++

и что, С++ меняет как сделаны в си подобные массивы? Если да, то нужно С++ смотреть, если нет, то не нужно

Kelbon
и что, С++ меняет как сделаны в си подобные массив...

Ну например в С++ нет vla, в Си — есть Уже что-то, но сломал

Kelbon
и что, С++ меняет как сделаны в си подобные массив...

В стандарте С++ есть, что массивы реализованы как линейна память. И есть то, что такая адресация уб

Kelbon
и что, С++ меняет как сделаны в си подобные массив...

Всегда надо смотреть в С++ стандарт, если ты про С++ говоришь

Kelbon
и что, С++ меняет как сделаны в си подобные массив...

ты путаешь стандарт и реализацию стандарта, стандарт дает гарантии сверху, компиляторы вряд ли будут после написания си компилятора менять реализацию в плюсовом компиляторе, но теоретически может, стандарт не запрещает. Спор о гарантиях которые дает стандарт, а не о реализациях

Yalokin Kononov
ты путаешь стандарт и реализацию стандарта, станда...

Не, он не путает Просто он подумал что массивы в С++ полностью скопипащщены из стандарта Си

Gleb Pylypets
так а если одним словом, то итог какой? я просто о...

Выходить за границы массива нельзя. Подмассив тоже является массивом, поэтому за его границы тоже нельзя вне зависимости от того, есть там следующий подмассив, или нет. Компилятор гипотетически (но только гипотетически) может увидеть, что мы напрямую не обращаемся к подмассивам a[1] и a[2] и удалить их, оставив только a[0]

Danya🔥
Не, он не путает Просто он подумал что массивы в С...

сомнительное утверждение что стандарт С++ дает такую гарантию

Kelbon
вот поэтому и надо знать, есть ли в стандарте си г...

И в стандарте C++ было, вроде, это не отменяет того, что так нельзя

Gleb-Pylypets Автор вопроса
Ofee Oficsu
И в стандарте C++ было, вроде, это не отменяет тог...

если было, то что значит нельзя? что может привести к UB?

Gleb Pylypets
если было, то что значит нельзя? что может привест...

Вы же не рассчитываете, что компилятор выделит память под неиспользованную переменную? В коде a[0][5] тоже ни a[1], ни a[2] не использованы, почему компилятор должен был выделить драгоценную память под них?

Gleb Pylypets
смысле неиспользованную?

Вы используете в коде только a[0]

Gleb-Pylypets Автор вопроса
Ofee Oficsu
Вы используете в коде только a[0]

а если буду всё использовать, то что будет?

Gleb-Pylypets Автор вопроса
Gleb Pylypets
а если буду всё использовать, то что будет?

я подразумевал, что всё используется, если это на что-то влияет.

Gleb Pylypets
я подразумевал, что всё используется, если это на ...

факт использования не отменяет UB, а уменьшает вероятность, что будет минус нога

Gleb Pylypets
я подразумевал, что всё используется, если это на ...

Это ничего не меняет. Я указал, как гипотетически ваш код может взорваться. То, что вы используете все элементы не изменит формулировку стандарта

Gleb-Pylypets Автор вопроса
Alexander Karaev
constexpr проверил - UB есть

Походу, в универе не считают, что там UB - можете ткнуть в стандарт, чтобы я смог проапеллировать ))

Gleb Pylypets
Походу, в универе не считают, что там UB - можете ...

Естественно, не считают. На моей памяти практически каждый достаточно взрослый препод считает своим долгом рассказать, что память линейная и что по многомерным массивам можно ходить как угодно. P.S. В стандарт не ткну

Gleb-Pylypets Автор вопроса
Gleb-Pylypets Автор вопроса
Ofee Oficsu
Можете попробовать

А если написать a[0][5], то не будет ли там каст к поинтеру после чего это становится валидным?

Gleb-Pylypets Автор вопроса

то есть array to pointer decay

Допустим, int* p = a[0]; Тогда p + 5 эквивалентно a[0][5]. Подставим все значения в неравенство из стандарта 0 ≤ i + j ≤ n, где i — это элемент массива (в нашем случае нулевой, поскольку p приводится к нему), j — это наше смещение на 5, а n — размер массива: 0 ≤ 0 + 5 ≤ 3. Что-то не сходится. С пунктом выше тоже не сходится, наш p — не нулевой указатель. Остаётся третий вариант: the behavior is undefined

Gleb-Pylypets Автор вопроса
Ofee Oficsu
Допустим, int* p = a[0]; Тогда p + 5 эквивалентно...

хм, а на что будет указывать a[0] - разве на массив из 3-х эллементов?

Gleb-Pylypets Автор вопроса
Gleb Pylypets
и это рассуждение не валидно?

Хотя вы и скрыли информацию о размере, после преобразования массива к int*, (*p) не перестаёт быть элементом исходного массива (просто потому что адресная арифметика в принципе применима только к указателям на элементы массива). А массивы всегда имеют некоторый размер n. И никакой факт преобразования не может изменить этот n

Похожие вопросы

Обсуждают сегодня

а через ESC-код ?
Alexey Kulakov
29
30500 за редактор? )
Владимир
47
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
13
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
program test; {$mode delphi} procedure proc(v: int32); overload; begin end; procedure proc(v: int64); overload; begin end; var x: uint64; begin proc(x); end. Уж не знаю...
notme
6
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
Вот еще странный косяк, подскажите как бороться. Я git clone сделал себе всего embassy и примеры там запускаю. Всё хорошо. Но вот решил в cargo.toml зависимости не как в приме...
Lukutin R2AJP
1
вы делали что-то подобное и как? может есть либы готовые? увидел картинку нокода, где всё линиями соединено и стало интересно попробовать то же в ddl на lua сделать. решил с ч...
Victor
8
Ребят в СИ можно реализовать ООП?
Николай
33
Карта сайта