powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / virtual methods
25 сообщений из 356, страница 10 из 15
virtual methods
    #39653226
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
упс, что-то с цитированием...
...
Рейтинг: 0 / 0
virtual methods
    #39653227
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
a guest((int *)buffer)[0] тоже в порядке.Ну или не в порядке, но std::launder я показывать не хочу, у народа с пониманием более простых вещей тут явные проблемы.
...
Рейтинг: 0 / 0
virtual methods
    #39653230
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestпринеси уже определение арифметики указателей для случая, когда указатель не указывает на элемент массива.
Сначала докажите что там не массив
...
Рейтинг: 0 / 0
virtual methods
    #39653231
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну так посмотрите: 7.2 Array-to-pointer conversion .
...
Рейтинг: 0 / 0
virtual methods
    #39653232
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BarloneНо вот это точно бред. С памятью, выделенной malloc, работать как с массивом вообще никак нельзя, да?

По драфту... если переводить дословно... нет ))), нельзя )))

http://eel.is/c draft/expr.add
For addition or subtraction, if the expressions P or Q have type “pointer to cv T”, where T and the array element type are not similar, the behavior is undefined.
...
Рейтинг: 0 / 0
virtual methods
    #39653234
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestМожно просто драфты смотреть, не обязательно покупать стандарт.
Текущая версия с удобной навигацией http://eel.is/c draft/
Сборник драфтов в .pdf-формате https://github.com/cplusplus/draft/tree/master/papers Давай будем читать "твои" черновики вместе... :)
draftWhen an expression that has integer type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the pointer operand points to an element of an array object, and the array is large enough, the result points to an element offset from the original element such that the difference of the subscripts of the resulting and original array elements equals the integer expression. In other words, if the expression P points to the i-th element of an array object, the expressions (P)+N (equivalently, N+(P)) and (P)-N (where N has the value n) point to, respectively, the i+n-th and i−n-th elements of the array object, provided they exist. Moreover, if the expression P points to the last element of an array object, the expression (P)+1 points one past the last element of the array object, and if the expression Q points one past the last element of an array object, the expression (Q)-1 points to the last element of the array object. If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined. If the result points one past the last element of the array object, it shall not be used as the operand of a unary * operator that is evaluated.
ПереводКогда выражение, имеющее целочисленный тип прибавлено или вычтено из указателя, результат имеет тип операнда указателя. Если операнд указателя указывает на объект элемента массива и массив достаточно велик, результат указывает на смещение элемента от начального элемента так, что разница индексов результирующего и начального элемента массива является целочисленным выражением. Иными словами, если выражение P указывает на i-тый объект элемента массива, выражение (P)+N (в арифметике указателей тоже, что N+(P)) и (P)-N (где N имеет значение n) указывают, соответственно, на i+n-ый и i-n-ый объект элементов массива, если они существуют. Более того, если выражение P указывает на объект последнего элемента массива, выражение (P)+1 указывает следующий объект элемента массива после последнего и если выражение Q указывает следующий после последнего объект элемента массива, выражение (Q)-1 указывает на последний объект элемента массива. Если оба, и операнд указателя, и результат указывают на один и тот же объект массива или на следующий за последним объект элемента массива, результатом оценки выражения не должно являться переполнение, в противном случае, поведение не определено. Если результат указыват на следующий за последним объект элемента массива, этот результат не должен быть использован в качестве операнда унарного оператора * (разыменование указателя).

Примечание: Здесь под элементом массива понимается некая абстрактная единица хранения массива, имеющая размер хранящегося в ней объекта, а под объектом элемента понимается экземпляр любого типа, хранящийся в элементе массива, а не только экземпляр какого-либо класса.

Иными словами, для твоего примера:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
UINT8 buffer[4 * sizeof(INT32)];

PUINT8 c = &buffer[15];           //-- Нет UB
PINT32 p = &((PINT32)buffer)[3];  //-- Нет UB
с += 1;  //-- нет UB !!! (тоже, что (&buffer[15])++ или &buffer[16])
p += 1;  //-- нет UB !!! (тоже, что (&((PINT32)buffer)[3])++ или &((PINT32)buffer)[4])
printf("%c, %i", *c, *p); //-- есть UB !!!
c += 1;  //-- есть UB !!!
p += 1;  //-- есть UB !!!


А теперь попробуй пояснить, как компилятор должен определить UB в подобном примере:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
UINT8 buffer[sizeof(int) << 2];
PUINT8 c = &buffer[8];
int direction;
for (int i = 0; i < 100; i++)
{
  direction = std::rand() - ((int)RAND_MAX >> 1);
  if (direction > 0)
    c++;
  else
    c--;
  printf("c = '%c'", *c);
}
...
Рейтинг: 0 / 0
virtual methods
    #39653235
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Barlonea guestBarloneЕсли почитать тот стандарт, что сам и приводил, и подумать, то (int*)buffer определен для [0..3].А если перечитать ещё раз (внимательно) и ещё подумать (подольше), то прибавление [0..3] к указателю (int*)buffer не определено, т.к. указатель (int*)buffer не является указателем на элемент массива нужного размера, т.к никакого массива из int там вообще нет.Но вот это точно бред.Аргументированно, как обычно на этом форуме.

BarloneС памятью, выделенной malloc, работать как с массивом вообще никак нельзя, да?Пока там не создан массив с помощью placement new — нельзя.
...
Рейтинг: 0 / 0
virtual methods
    #39653236
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest, так вы правда утверждаете, что с памятью, выделенной malloc, нельзя работать как с массивом?
...
Рейтинг: 0 / 0
virtual methods
    #39653239
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovskya guestпринеси уже определение арифметики указателей для случая, когда указатель не указывает на элемент массива.
Сначала докажите что там не массив Запросто: его там не создавали, значит его там нет.
Если вы не знаете таких базовых вещей (как создаются объекты в C++), зачем лезете?
...
Рейтинг: 0 / 0
virtual methods
    #39653240
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну в целом смысл закладываемый драфтом, понятен

1) за "ручное" cast'ование типов, draft ответственности не несет.
2) операции могут перегружаться. Т.ч. даже "выход за пределы массива" (кроме элемента сразу за последним), undefined. Т.к. если там какая-то коллекция, то она может такие факты и проверить.

IMHO

P.S. Перефразируя известное проклятие "что бы тебе всю жизнь программировать строго следуя спецификациям" )))
...
Рейтинг: 0 / 0
virtual methods
    #39653241
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Barlonea guestBasil A. Sidorov, ладно, объясняю на пальцах.

Пусть тип элемента вектора T = int.

Вот есть у нас кусок памяти под 4 элемента (для простоты — статический массив):
Код: plaintext
1.
unsigned char buffer[4*sizeof(int)];



Пусть в векторе 3 элемента 5, 10, 33. Их вектор создал с помощью placement new:
Код: plaintext
1.
2.
3.
new (buffer + 0*sizeof(int)) int {5};
new (buffer + 1*sizeof(int)) int {10};
new (buffer + 2*sizeof(int)) int {33};



Теперь что примерно делает оператор[]? Вот это
Код: plaintext
1.
2.
3.
4.
int& operator[](size_t n)
{
    return reinterpret_cast<int*>(buffer)[n];
}


А это точно приведёт к UB для n == 2, т.к. индексация == адресная арифметика, а она определена только в пределах массива. Никакого массива из int-ов в буфере нет.На самом деле, UB тут есть, но совсем в другом месте. unsigned char buffer[4*sizeof(int)] не гарантирует нужного для int выравнивания, и даже обращение к ((int *)buffer)[0] может привести к проблемам.
Такое бывает на некоторых архитектурах (int только по четным адресам), но тогда placement new бы ругнулся
...
Рейтинг: 0 / 0
virtual methods
    #39653242
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestЗапросто: его там не создавали, значит его там нет.
Код: plaintext
1.
2.
3.
{
   int a[2];
}


Вот тут массив создан или нет?
...
Рейтинг: 0 / 0
virtual methods
    #39653243
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Leonid Kudryavtsev1) за "ручное" cast'ование типов, draft ответственности не несет.То есть? Поведение многих кастов вполне описано и определено.
...
Рейтинг: 0 / 0
virtual methods
    #39653246
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovskya guestЗапросто: его там не создавали, значит его там нет.
Код: plaintext
1.
2.
3.
{
   int a[2];
}


Вот тут массив создан или нет?Детсадовская попытка подловить, дописав что-нибудь над и под фигурными скобками, которые сделают любой мой ответ неверным?
...
Рейтинг: 0 / 0
virtual methods
    #39653247
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestBarloneпропущено...
Но вот это точно бред.Аргументированно, как обычно на этом форуме. 21457288
Какие тебе еще нужны аргументы? :)

a guestBarloneС памятью, выделенной malloc, работать как с массивом вообще никак нельзя, да?Пока там не создан массив с помощью placement new — нельзя. Неужели? Забавно, но в Си нет ни new, ни placement new, однако, библиотечным функциям работы со строками (strlen, strcpy и т.д.), а также библиотечным функциям работы с памятью (memcpy, memset, memmove и т.д.) сей факт абсолютно никак не мешает, при том, что Си, как я уже упоминал, является для C++ наследием.
...
Рейтинг: 0 / 0
virtual methods
    #39653249
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestAnatoly Moskovskyпропущено...
Сначала докажите что там не массив Запросто: его там не создавали, значит его там нет.
Если вы не знаете таких базовых вещей (как создаются объекты в C++), зачем лезете?
В мемориз! Скриньте это, парни!!!
...
Рейтинг: 0 / 0
virtual methods
    #39653250
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestКак, если ты даже не умеешь читать? Покажи, с какого драфта ты скопировал то, что у тебя написано под спойлером.С какого драфта ты это цитировал, с того и взято. Я просто взял твою цитату драфта.
...
Рейтинг: 0 / 0
virtual methods
    #39653252
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestПока там не создан массив с помощью placement new — нельзя. Неужели? Забавно, но в Си нет ни new, ни placement new, однако, библиотечным функциям работы со строками (strlen, strcpy и т.д.), а также библиотечным функциям работы с памятью (memcpy, memset, memmove и т.д.) сей факт абсолютно никак не мешаетВ C и C++ разная семантика создания объектов. Аналогии с C тут не к месту.
rdb_devСи, как я уже упоминал, является для C++ наследием.Отсюда не следует ничего.
...
Рейтинг: 0 / 0
virtual methods
    #39653258
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestДетсадовская попытка подловить, дописав что-нибудь над и под фигурными скобками, которые сделают любой мой ответ неверным?
Код: plaintext
1.
2.
3.
4.
{
   int a[2];
   // Вот тут массив создан или нет?
}


Ответ-то есть?
...
Рейтинг: 0 / 0
virtual methods
    #39653260
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovskya guestДетсадовская попытка подловить, дописав что-нибудь над и под фигурными скобками, которые сделают любой мой ответ неверным?
Код: plaintext
1.
2.
3.
4.
{
   int a[2];
   // Вот тут массив создан или нет?
}


Ответ-то есть?Открой стандарт (или драфт). Там написано, как создаются объекты.
...
Рейтинг: 0 / 0
virtual methods
    #39653261
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devпропущено...
Неужели? Забавно, но в Си нет ни new, ни placement new, однако, библиотечным функциям работы со строками (strlen, strcpy и т.д.), а также библиотечным функциям работы с памятью (memcpy, memset, memmove и т.д.) сей факт абсолютно никак не мешаетВ C и C++ разная семантика создания объектов. Аналогии с C тут не к месту.В Си нет классов, а массивы есть! :)

a guestrdb_devСи, как я уже упоминал, является для C++ наследием.Отсюда не следует ничего.Как же не к месту, если C++ полностью наследует Си, включая создание массивов, приведение указателей и арифметику указателей? O_o
...
Рейтинг: 0 / 0
virtual methods
    #39653266
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestLeonid Kudryavtsev1) за "ручное" cast'ование типов, draft ответственности не несет.То есть? Поведение многих кастов вполне описано и определено.

Я про желание скастовать массив char[] в массив int[]

rdb_deva guestпропущено...
Запросто: его там не создавали, значит его там нет.
Если вы не знаете таких базовых вещей (как создаются объекты в C++), зачем лезете?
В мемориз! Скриньте это, парни!!!

Вот честно говоря, ничего смешного не увидел

A.Quest совершенно прав
Там массив char (и при этом даже "не сырая" память от какого нибудь malloc'а, а "честный" массив char)
А массив int, это массив другого типа.

То, что это относительно однозначно будет работать на Intel архитектуре - всем понятно. Но стандарты на язык пишутся для разных архитектур. Об одном подводном камне (выравнивание) уже вспомнили.
...
Рейтинг: 0 / 0
virtual methods
    #39653271
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_devC++ полностью наследует СиЭто не так.
...
Рейтинг: 0 / 0
virtual methods
    #39653274
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Leonid KudryavtsevОб одном подводном камне (выравнивание) уже вспомнили.Я просто забыл написать alignas. Цель примера была показать не проблемы с выравниванием, об этом и так многие знают. Считайте, что с выравниванием всё ок.
...
Рейтинг: 0 / 0
virtual methods
    #39653276
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestОткрой стандарт (или драфт). Там написано, как создаются объекты.
Понятно, т.е. ответа нет.

Из этого можно сделать вывод что мальчик путает созданный массив и проинициализированный массив, и не считает первое массивом
...
Рейтинг: 0 / 0
25 сообщений из 356, страница 10 из 15
Форумы / C++ [игнор отключен] [закрыт для гостей] / virtual methods
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]