Size: a a a

2021 March 14

АК

Александр Караев... in pro.cxx
Stas Koynov
НЕТ это УБ, там живут маленькие гномики!
Не первый раз вижу от вас язвительные комментарии уровня супапро по отношению к стандарту. Не желаете слушать, так не распространяйте лженауку здесь
источник

BU

Boris Usievich in pro.cxx
Andrey Glebov
Из https://eel.is/c++draft/dcl.array#9 получается что "многомерный массив" это просто массив массивов.
Это почти как std::array<std::array<int, 5>, 3>.  Мы же не можем безопасно скастить указатель на объект этого типа к указателю на std::aray<int, 15>.
Не путайте классы  с POD. POD  Наследуют поведение из С :)
источник

АК

Александр Караев... in pro.cxx
Stas Koynov
изыди сатана. ЭТО УБ, грязный указатель без шаред_пойнтера как ты вообще на ++ пишешь
А это вообще к теме не относится, чушь какая-то :)
источник

AG

Andrey Glebov in pro.cxx
Boris Usievich
Не путайте классы  с POD. POD  Наследуют поведение из С :)
не путаю, как раз сказал, что "это почти как"
источник

SK

Stas Koynov in pro.cxx
Александр Караев
Не первый раз вижу от вас язвительные комментарии уровня супапро по отношению к стандарту. Не желаете слушать, так не распространяйте лженауку здесь
ну я привел доказательства где кастить можно, что лежат последовательно привел цитаты из стандарта, что там все лежит последовательно. вы говорите что я говорю чушь. я уже вообще ничего не понимаю.
источник

W

Wild_Wind in pro.cxx
Boris Usievich
Не путайте классы  с POD. POD  Наследуют поведение из С :)
*
pod deprecated in c++20.
use "trivial"
источник

SS

Sergey Skvortsov in pro.cxx
Stas Koynov
7.2 Array-to-pointer conversion [conv.array]
1 An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue of
type “pointer to T”. The temporary materialization conversion (7.4) is applied. The result is a pointer to the
first element of the array.

11.3.4 Arrays
7
[ Note: A consistent rule is followed for multidimensional arrays. If E is an n-dimensional array of rank
i × j × · · · × k, then E appearing in an expression that is subject to the array-to-pointer conversion (7.2)
is converted to a pointer to an (n − 1)-dimensional array with rank j × · · · × k. If the * operator, either
explicitly or implicitly as a result of subscripting, is applied to this pointer, the result is the pointed-to
(n − 1)-dimensional array, which itself is immediately converted into a pointer. [ Example: Consider
int x[3][5];
Here x is a 3 × 5 array of integers. When x appears in an expression, it is converted to a pointer to (the first
of three) five-membered arrays of integers. In the expression x[i] which is equivalent to *(x+i), x is first
converted to a pointer as described; then x+i is converted to the type of x, which involves multiplying i by
the length of the object to which the pointer points, namely five integer objects. The results are added and
indirection applied to yield an array (of five integers), which in turn is converted to a pointer to the first of
the integers. If there is another subscript the same argument applies again; this time the result is an integer.
— end example ] — end note ]
С++17 2017-03-21 Revises: N4640
Это доказательство?
Нерелевантная note + описание array to pointer conversion, которое не говорит ничего про то, что можно с этим указателем делать после
источник

BU

Boris Usievich in pro.cxx
Wild_Wind
*
pod deprecated in c++20.
use "trivial"
не суть как называть
источник

W

Wild_Wind in pro.cxx
Эх.
Сначала забиваем на устаревания named requirements, а потом и arr[4][5] к arr[20] кастим...
:(
источник

VS

Vlad Serebrennikov in pro.cxx
мне кажется, что без цитаты или логической цепочки на основе цитат, что T[N][M] это T[N*M], начало expr.add#4.2 однозначно говорит о том, что арифметика указателей не будет работать для всех элементов двумерного массива одновременно

при этом я вижу лишь, что T[N][M] это массив массивов. как в нормативном тексте, так и в примечаниях
источник

SK

Stas Koynov in pro.cxx
Wild_Wind
Эх.
Сначала забиваем на устаревания named requirements, а потом и arr[4][5] к arr[20] кастим...
:(
ок в следущий раз вместо memset(arr, 0, sizeof(arr))
буду делать
for(row =...)
 for (col )
ведь так правильнее. без нарушений и стирания типа.
источник

W

Wild_Wind in pro.cxx
Stas Koynov
ок в следущий раз вместо memset(arr, 0, sizeof(arr))
буду делать
for(row =...)
 for (col )
ведь так правильнее. без нарушений и стирания типа.
Надеюсь, в constexpr контексте?
Тогда это будет даже эффективнее.
источник

ПК

Побитый Кирпич... in pro.cxx
Wild_Wind
Эх.
Сначала забиваем на устаревания named requirements, а потом и arr[4][5] к arr[20] кастим...
:(
не к arr[20] а к Int*
источник

АК

Александр Караев... in pro.cxx
Stas Koynov
ну я привел доказательства где кастить можно, что лежат последовательно привел цитаты из стандарта, что там все лежит последовательно. вы говорите что я говорю чушь. я уже вообще ничего не понимаю.
Лэйаут памяти сам по себе ничего не гарантирует. Возможность разыменовывать не определяется тем, что указатель "попал" в валидный элемент.
int a[3]
int* p = &a[0];
(p+10)-10 - мы может и получим тот же указатель с точки зрения здравого смысла, однако это UB, если я правильно помню.
источник

W

Wild_Wind in pro.cxx
Побитый Кирпич
не к arr[20] а к Int*
Шо то разные типы, шо это.
источник

ПК

Побитый Кирпич... in pro.cxx
Wild_Wind
Шо то разные типы, шо это.
Ну arr[N] к int* же ты можешь сконвертить, хоть это и разные типы
источник

VS

Vlad Serebrennikov in pro.cxx
Александр Караев
Лэйаут памяти сам по себе ничего не гарантирует. Возможность разыменовывать не определяется тем, что указатель "попал" в валидный элемент.
int a[3]
int* p = &a[0];
(p+10)-10 - мы может и получим тот же указатель с точки зрения здравого смысла, однако это UB, если я правильно помню.
да, уб
источник

IZ

Ilia Zviagin in pro.cxx
Andrey Glebov
Из https://eel.is/c++draft/dcl.array#9 получается что "многомерный массив" это просто массив массивов.
Это почти как std::array<std::array<int, 5>, 3>.  Мы же не можем безопасно скастить указатель на объект этого типа к указателю на std::aray<int, 15>.
Нет, вот это уже нельзя
источник

IA

Ilia Abernikhin in pro.cxx
не могу сказать что прям глубоко понял суть проблемы которую вы обсуждаете, но следуюший код отрабатывает совершенно коректно

#include <iostream>

void foo(int* array, size_t size);

int main() {
   int array[3][5] = {0};

   foo(array[0], 15);

   return 0;
}

void foo(int* array, size_t size) {
   for (int i = 0; i < size; ++i)
       std::cout << *(array + i) << std::endl;
}

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

VS

Vlad Serebrennikov in pro.cxx
Ilia Abernikhin
не могу сказать что прям глубоко понял суть проблемы которую вы обсуждаете, но следуюший код отрабатывает совершенно коректно

#include <iostream>

void foo(int* array, size_t size);

int main() {
   int array[3][5] = {0};

   foo(array[0], 15);

   return 0;
}

void foo(int* array, size_t size) {
   for (int i = 0; i < size; ++i)
       std::cout << *(array + i) << std::endl;
}

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