powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / virtual methods
25 сообщений из 356, страница 9 из 15
virtual methods
    #39653033
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Barlonea guestпропущено...
А зачем он нужен, если ничего не делает? Можно не вызвать его тогда...
Так это, placement new конструкторы вызывает.Спасибо, я в курсе.
Не я утверждал, что placement new ничего не делает.
...
Рейтинг: 0 / 0
virtual methods
    #39653038
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a 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-ов в буфере нет.Бред.
Или предъяви компилятор, в котором это работает не так как ожидается.
...
Рейтинг: 0 / 0
virtual methods
    #39653047
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SiemarglБред.Аргументированно.
...
Рейтинг: 0 / 0
virtual methods
    #39653060
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestSiemarglБред.Аргументированно.Для тех, кто пользуется компилятором, вполне аргументировано. Религия не позволяет скомпилировать и пройтись отладчиком?
...
Рейтинг: 0 / 0
virtual methods
    #39653079
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestSiemarglБред.Аргументированно.Если почитать тот стандарт, что сам и приводил, и подумать, то (int*)buffer определен для [0..3].

для очистки совести можно завести еще переменную
Код: plaintext
1.
2.
3.
4.
5.
    char buffer[4*sizeof(int)];
    
    int *buffer2 = (int*)buffer;
    
    buffer2[2] = 3;
...
Рейтинг: 0 / 0
virtual methods
    #39653084
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SiemarglЕсли почитать тот стандарт, что сам и приводил, и подумать, то (int*)buffer определен для [0..3].

для очистки совести можно завести еще переменную
Код: plaintext
1.
2.
3.
4.
5.
    char buffer[4*sizeof(int)];
    
    int *buffer2 = (int*)buffer;
    
    buffer2[2] = 3;

Я ему об этом уже писал 21455915 , но он не читает и ничего компилировать и проверять не хочет. Просто троллит.
...
Рейтинг: 0 / 0
virtual methods
    #39653087
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Siemargla guestпропущено...
Аргументированно.Если почитать тот стандарт, что сам и приводил, и подумать, то (int*)buffer определен для [0..3].А если перечитать ещё раз (внимательно) и ещё подумать (подольше), то прибавление [0..3] к указателю (int*)buffer не определено, т.к. указатель (int*)buffer не является указателем на элемент массива нужного размера, т.к никакого массива из int там вообще нет.
...
Рейтинг: 0 / 0
virtual methods
    #39653117
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestА если перечитать ещё раз (внимательно) и ещё подумать (подольше), то прибавление [0..3] к указателю (int*)buffer не определено, т.к. указатель (int*)buffer не является указателем на элемент массива нужного размера, т.к никакого массива из int там вообще нет.Еще раз (сбился со счёта - в какой) - твой массив состоит из 16-ти элементов unsigned char ( unsigned char buffer[4 * sizeof(int)] ) и в нём прекрасно умещается 4 элемента любого типа размером 4 байта (UINT32, INT32 или int в моделях ILP32, I32LP64, LLP64, LP64), поэтому, для доступа к этим 4-ём элементам int ничто не мешает использовать приведенный к int* указатель на массив buffer, а также использовать арифметику указателей с обычный указателем на unsigned char:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
  UINT8 buffer[sizeof(INT32)<<2];
  
  PINT32 p = (PINT32)buffer;
  *(p++) = 0x33323130; *(p++) = 0x37363534; *(p++) = 0x3b3a3938;
  PINT8 c = buffer;
  for (int i = 0; i < sizeof(buffer); i++)
  {
    printf("buffer[%i] = '%c'; *c = '%c'\r\n", i, buffer[i], *(c++));
  }
...
Рейтинг: 0 / 0
virtual methods
    #39653123
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestЗатем, что дальше написано, что otherwise behavior is undefined.
Вы читать-то научитесь.
Вот вся фраза.
"If the expression P points to element x[i] of an array object x with n elements, the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element x[i+j] if 0≤i+j≤n; otherwise, the behavior is undefined"
В ней утверждается,что
1) Если x массив длиной N
2) Есть выражение P равное &x[i]
3) То выражение P + j равно &x[i + j] если 0<=i+j<=n
4) А если не выполняется 0<=i+j<=n, то выражение P + j дает UB (а вовсе не "если это не массив, то UB", как вы в порядке бреда поняли ).
...
Рейтинг: 0 / 0
virtual methods
    #39653135
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovskya guestЗатем, что дальше написано, что otherwise behavior is undefined.
Вы читать-то научитесь.
Вот вся фраза.
"If the expression P points to element x[i] of an array object x with n elements, the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element x[i+j] if 0≤i+j≤n; otherwise, the behavior is undefined"
В ней утверждается,что
1) Если x массив длиной N
2) Есть выражение P равное &x[i]
3) То выражение P + j равно &x[i + j] если 0<=i+j<=n
4) А если не выполняется 0<=i+j<=n, то выражение P + j дает UB (а вовсе не "если это не массив, то UB", как вы в порядке бреда поняли )."otherwise" относится к "If". Какое-то из условий в if не выполнено — UB.

Короче, если ты хочешь показать, что я принёс не ту цитату из стандарта, притащи определение арифметики указателей для случая, когда указатель не указывает на элемент массива. И пруф вот этой Anatoly Moskovskyи никакой массив тут и не требуется. Достаточно чтобы там, по вычисленному адресу, который разыменовывается, был валидный объект чуши.
...
Рейтинг: 0 / 0
virtual methods
    #39653138
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Siemargla guestпропущено...
А если перечитать ещё раз (внимательно) и ещё подумать (подольше), то прибавление [0..3] к указателю (int*)buffer не определено, т.к. указатель (int*)buffer не является указателем на элемент массива нужного размера, т.к никакого массива из int там вообще нет.С тобой нет смысла разговаривать.Естественно. У тебя из "аргументов" только "Бред". Ни одной ссылки на стандарт. Пукнул в лужу, а когда тебе отказались верить без обоснований — слился.
...
Рейтинг: 0 / 0
virtual methods
    #39653140
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestAnatoly Moskovsky"If ... if 0≤i+j≤n; otherwise, the behavior is undefined""otherwise" относится к "If".К какому из двух, говорите???
...
Рейтинг: 0 / 0
virtual methods
    #39653145
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Basil A. Sidorova guestпропущено...
"otherwise" относится к "If".К какому из двух, говорите???Точку с запятой перед otherwise видишь? Что она значит? Почему там не запятая?
...
Рейтинг: 0 / 0
virtual methods
    #39653149
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest"otherwise" относится к "If". Какое-то из условий в if не выполнено — UB.
Нет. Учите язык.

Во фразе
"If A, B if C; otherwise, D" otherwise относится к if C, потому что во-первых оно ближе, во вторых первый if отделен запятой, то есть это предусловия для всей оставшейся фразы.
...
Рейтинг: 0 / 0
virtual methods
    #39653159
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestТочку с запятой перед otherwise видишь? Что она значит? Почему там не запятая?"Ты идешь по очень тонкому льду, мой друг педигрипал" (ц) Кирпич.вводнаяIf the expression P points to element x[i] of an array object x with n elements, логический разделительthe expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element x[i+j]определение эквивалентностиif 0≤i+j≤nусловие, нарушение которого даёт неопределённое поведение.

P.S.
А точку с запятой, обычно, ставят там, где не хотят начинать новое предложение.
"А Владимир Ильич всё бреется; а мог бы и полоснуть".
...
Рейтинг: 0 / 0
virtual methods
    #39653163
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чтобы было еще понятнее

"If A, B if C; otherwise, D" надо читать так:

"If A and C then B else if not (A and C) then D"
...
Рейтинг: 0 / 0
virtual methods
    #39653165
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Упс, запутался раскрывая скобки

Вот так:
"If A and C then B else if A and not C then D"
...
Рейтинг: 0 / 0
virtual methods
    #39653173
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovskya guest"otherwise" относится к "If". Какое-то из условий в if не выполнено — UB.
Нет. Учите язык.И вам того же.

Anatoly MoskovskyВо фразе
"If A, B if C; otherwise, D" otherwise относится к if CНет.
Anatoly Moskovskyоно ближеВот поэтому приходится использовать точку с запятой, чтобы показать, что otherwise относится ко всему первому простому предложению сложного предложения, а не к ближайшему if.
Точка с запятой разделяет (и связывает) более "масштабные" части предложения, чем запятая. Запятая внутри простого предложения, точка с запятой — для разделения (связывания) простых предложений сложного предложения.
...
Рейтинг: 0 / 0
virtual methods
    #39653176
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Basil A. SidorovА точку с запятой, обычно, ставят там, где не хотят начинать новое предложение.Золотые слова. Подтверждает вышенаписанное мной про разделение простых предложений сложного предложения. Можно превратить сложное предложение в 2 простых, разделив вместо точки запятой точкой.
...
Рейтинг: 0 / 0
virtual methods
    #39653177
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyЧтобы было еще понятнеепринеси уже определение арифметики указателей для случая, когда указатель не указывает на элемент массива.
...
Рейтинг: 0 / 0
virtual methods
    #39653201
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Где найти стандарт, не знаю. Попытался читать результаты гугля по "pointer arithmetic" и складывается ощущение, что a guest прав

Наиболее "читаемый" текст по ссылке http://en.cppreference.com/w/cpp/language/operator_arithmetic

MSDN так же, про pointer arithmetic говорит исключительно о массивах. Даже в книжке Programming in C: A Tutorial
Brian W. Kernighan примеры (одна страничка) исключительно о перемещениях по массиву.

IMHO

note: стандарта не знаю, не читал. Но в google, что либо противоречащие мнению a.guest найти не смог. Где взять стандарт, не знаю.


If any of the operands is a pointer, the following rules apply:

* A pointer to non-array object is treated as a pointer to the first element of an array with size 1.
* If the pointer P points to the ith element of an array, then the expressions P+n, n+P, and P-n are pointers of the same type that point to the i+nth, i+nth, and i-nth element of the same array, respectively. The result of pointer addition may also be a one-past-the-end pointer (that is, pointer P such that the expression P-1 points to the last element of the array). Any other situations (that is, attempts to generate a pointer that isn't pointing at an element of the same array or one past the end) invoke undefined behavior.
* If the pointer P points to the ith element of an array, and the pointer Q points at the jth element of the same array, the expression P-Q has the value i-j, if the value fits in std::ptrdiff_t. Both operands must point to the elements of the same array (or one past the end), otherwise the behavior is undefined. If the result does not fit in std::ptrdiff_t, the behavior is undefined.
* In any case, if the pointed-to type is different from the array element type, disregarding cv qualifications, at every level if the elements are themselves pointers, the behavior of pointer arithmetic is undefined. In particular, pointer arithmetic with pointer to base, which is pointing at an element of an array of derived objects is undefined.
* If the value ​0​ is added or subtracted from a pointer, the result is the pointer, unchanged. If two pointers point at the same object or are both one past the end of the same array, or both are null pointers, then the result of subtraction is equal to (std::ptrdiff_t)0.

...
Рейтинг: 0 / 0
virtual methods
    #39653202
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Leonid KudryavtsevГде найти стандарт, не знаю.Можно просто драфты смотреть, не обязательно покупать стандарт.
Текущая версия с удобной навигацией http://eel.is/c draft/
Сборник драфтов в .pdf-формате https://github.com/cplusplus/draft/tree/master/papers
...
Рейтинг: 0 / 0
virtual methods
    #39653222
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a 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] может привести к проблемам.
...
Рейтинг: 0 / 0
virtual methods
    #39653223
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BarloneНа самом деле, UB тут есть, но совсем в другом месте. unsigned char buffer[4*sizeof(int)] не гарантирует нужного для int выравнивания, и даже обращение к ((int *)buffer)[0] может привести к проблемам.Считай, там есть alignas(int) и с созданием объектов с помощью placement new всё в порядке. ((int *)buffer)[0] тоже в порядке.
...
Рейтинг: 0 / 0
virtual methods
    #39653225
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestЕсли почитать тот стандарт, что сам и приводил, и подумать, то (int*)buffer определен для [0..3].А если перечитать ещё раз (внимательно) и ещё подумать (подольше), то прибавление [0..3] к указателю (int*)buffer не определено, т.к. указатель (int*)buffer не является указателем на элемент массива нужного размера, т.к никакого массива из int там вообще нет.[/quot]Но вот это точно бред. С памятью, выделенной malloc, работать как с массивом вообще никак нельзя, да?
...
Рейтинг: 0 / 0
25 сообщений из 356, страница 9 из 15
Форумы / C++ [игнор отключен] [закрыт для гостей] / virtual methods
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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