* [devel] memcpy глючит (или я не умею его готовить)
@ 2019-02-21 13:17 Paul Wolneykien
2019-02-21 13:22 ` Vladimir Didenko
2019-02-21 13:25 ` Alexey V. Vissarionov
0 siblings, 2 replies; 15+ messages in thread
From: Paul Wolneykien @ 2019-02-21 13:17 UTC (permalink / raw)
To: ALT Linux Team development discussions
Коллеги, прошу помощи разбором одной проблемы. Предполагаю, что это
какая-то очевидная ошибка: то ли я действительно не умею готовить
memcpy(), то ли где-то в программе есть ошибки при работе с памятью,
которые влияют косвенно (может в данном случае такое быть?).
Итак, у меня есть вот такой код¹
> 1460 if (_data.size % 2 && _data.data[8] == 0x04) {
> 1461 // Uncompressed point (the first 8 bytes is the UKM)
> 1462 memcpy (_data.data + 8, _data.data + 9, _data.size - 9);
> 1463 _data.size--;
> 1464 }
после выполнения которого на Сизифе, я получаю копию массива данных за
исключением 9-го (по счёту с 1) байта. Как и планировалось. Однако, если
тот же самый бинарь запустить на машинке с p8, то получается неожиданный
и странный эффект: 57-й байт заменяется копией 58-го. Вот
как это выглядит (см. конец строки 0x4cc050 – начало строки 0x4cc058 во
втором дампе):
> (gdb) x/73ubfx _data.data
> 0x4cc020: 0xdd 0x0a 0x35 0x80 0x51 0x13 0xed 0xdb
> 0x4cc028: 0x04 0xd6 0x9b 0xa0 0x15 0x3b 0xa2 0x72
> 0x4cc030: 0x98 0x72 0xd0 0x2a 0x64 0x45 0x79 0x05
> 0x4cc038: 0x4e 0x0f 0x74 0x4e 0x70 0x07 0xa9 0x4f
> 0x4cc040: 0x87 0x53 0xb4 0x55 0xd3 0xc6 0x81 0x48
> 0x4cc048: 0x90 0xbd 0xa1 0xff 0x28 0x7e 0x97 0x41
> 0x4cc050: 0x2a 0x6e 0xbf 0x5e 0xfc 0xa0 0xf4 0x2b
> 0x4cc058: 0xcd 0x47 0x64 0x36 0x46 0xb0 0x02 0x7b
> 0x4cc060: 0x11 0x03 0xe6 0x9c 0xed 0x94 0x43 0x50
> 0x4cc068: 0xdf
>
> (gdb) n
> 1463
>
> (gdb) x/73ubfx _data.data
> 0x4cc020: 0xdd 0x0a 0x35 0x80 0x51 0x13 0xed 0xdb
> 0x4cc028: 0xd6 0x9b 0xa0 0x15 0x3b 0xa2 0x72 0x98
> 0x4cc030: 0x72 0xd0 0x2a 0x64 0x45 0x79 0x05 0x4e
> 0x4cc038: 0x0f 0x74 0x4e 0x70 0x07 0xa9 0x4f 0x87
> 0x4cc040: 0x53 0xb4 0x55 0xd3 0xc6 0x81 0x48 0x90
> 0x4cc048: 0xbd 0xa1 0xff 0x28 0x7e 0x97 0x41 0x2a
> 0x4cc050: 0x6e 0xbf 0x5e 0xfc 0xa0 0xf4 0x2b 0x47
> 0x4cc058: 0x47 0x64 0x36 0x46 0xb0 0x02 0x7b 0x11
> 0x4cc060: 0x03 0xe6 0x9c 0xed 0x94 0x43 0x50 0xdf
> 0x4cc068: 0xdf
На других входных данных пока не пробовал. Зато пробовал на разных
машинах с Сизифом и p8 — воспроизводится стабильно. Причём, один из
Сизифов не самый новый. Однако на Сизифах работает, а на p8 — получаю
паразитную копию того самого 57-го байта. Архитектуры везде x86_64.
---
¹
http://git.altlinux.org/gears/g/gnupg-pkcs11-scd.git?p=gnupg-pkcs11-scd.git;a=blob;f=gnupg-pkcs11-scd/gnupg-pkcs11-scd/command.c;h=6fd39a8ef70dede06e54c49ab86bdfc2c01e74c3;hb=6bda8fd5e3b3862edca3a38ac62c01477b6ab909#l1460
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [devel] memcpy глючит (или я не умею его готовить)
2019-02-21 13:17 [devel] memcpy глючит (или я не умею его готовить) Paul Wolneykien
@ 2019-02-21 13:22 ` Vladimir Didenko
2019-02-21 13:28 ` Paul Wolneykien
2019-02-21 13:25 ` Alexey V. Vissarionov
1 sibling, 1 reply; 15+ messages in thread
From: Vladimir Didenko @ 2019-02-21 13:22 UTC (permalink / raw)
To: ALT Linux Team development discussions
чт, 21 февр. 2019 г. в 16:17, Paul Wolneykien:
>
>
> Коллеги, прошу помощи разбором одной проблемы. Предполагаю, что это
> какая-то очевидная ошибка: то ли я действительно не умею готовить
> memcpy(), то ли где-то в программе есть ошибки при работе с памятью,
> которые влияют косвенно (может в данном случае такое быть?).
>
> Итак, у меня есть вот такой код¹
>
> > 1460 if (_data.size % 2 && _data.data[8] == 0x04) {
> > 1461 // Uncompressed point (the first 8 bytes is the UKM)
> > 1462 memcpy (_data.data + 8, _data.data + 9, _data.size - 9);
> > 1463 _data.size--;
> > 1464 }
>
У вас участки памяти источника и приемника перекрываются, а это
неопределенное поведение. Вам memove() нужен.
--
С уважением,
Владимир.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [devel] memcpy глючит (или я не умею его готовить)
2019-02-21 13:17 [devel] memcpy глючит (или я не умею его готовить) Paul Wolneykien
2019-02-21 13:22 ` Vladimir Didenko
@ 2019-02-21 13:25 ` Alexey V. Vissarionov
2019-02-22 19:27 ` Leonid Krivoshein
1 sibling, 1 reply; 15+ messages in thread
From: Alexey V. Vissarionov @ 2019-02-21 13:25 UTC (permalink / raw)
To: ALT Linux Team development discussions
On 2019-02-21 16:17:07 +0300, Paul Wolneykien wrote:
> Коллеги, прошу помощи разбором одной проблемы. Предполагаю,
> что это какая-то очевидная ошибка: то ли я действительно не
> умею готовить memcpy(), то ли где-то в программе есть ошибки
> при работе с памятью, которые влияют косвенно (может в данном
> случае такое быть?).
> Итак, у меня есть вот такой код
>> 1460 if (_data.size % 2 && _data.data[8] == 0x04) {
(_data.size % 2) лично я поменял бы на (_data.size & 0x01)
>> 1461 // Uncompressed point (the first 8 bytes is the UKM)
>> 1462 memcpy (_data.data + 8, _data.data + 9, _data.size - 9);
>> 1463 _data.size--;
>> 1464 }
Наверняка какая-нибудь грабля с выравниванием...
--
Alexey V. Vissarionov
gremlin ПРИ altlinux ТЧК org; +vii-cmiii-ccxxix-lxxix-xlii
GPG: 0D92F19E1C0DC36E27F61A29CD17E2B43D879005 @ hkp://keys.gnupg.net
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [devel] memcpy глючит (или я не умею его готовить)
2019-02-21 13:22 ` Vladimir Didenko
@ 2019-02-21 13:28 ` Paul Wolneykien
0 siblings, 0 replies; 15+ messages in thread
From: Paul Wolneykien @ 2019-02-21 13:28 UTC (permalink / raw)
To: devel
21.02.2019 16:22, Vladimir Didenko пишет:
> чт, 21 февр. 2019 г. в 16:17, Paul Wolneykien:
>>
>>
>> Коллеги, прошу помощи разбором одной проблемы. Предполагаю, что это
>> какая-то очевидная ошибка: то ли я действительно не умею готовить
>> memcpy(), то ли где-то в программе есть ошибки при работе с памятью,
>> которые влияют косвенно (может в данном случае такое быть?).
>>
>> Итак, у меня есть вот такой код¹
>>
>>> 1460 if (_data.size % 2 && _data.data[8] == 0x04) {
>>> 1461 // Uncompressed point (the first 8 bytes is the UKM)
>>> 1462 memcpy (_data.data + 8, _data.data + 9, _data.size - 9);
>>> 1463 _data.size--;
>>> 1464 }
>>
>
> У вас участки памяти источника и приемника перекрываются, а это
> неопределенное поведение. Вам memove() нужен.
Как интересно. Спасибо!
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [devel] memcpy глючит (или я не умею его готовить)
2019-02-21 13:25 ` Alexey V. Vissarionov
@ 2019-02-22 19:27 ` Leonid Krivoshein
2019-02-22 20:51 ` Vladimir Didenko
0 siblings, 1 reply; 15+ messages in thread
From: Leonid Krivoshein @ 2019-02-22 19:27 UTC (permalink / raw)
To: devel
21.02.2019 16:25, Alexey V. Vissarionov пишет:
> On 2019-02-21 16:17:07 +0300, Paul Wolneykien wrote:
>
> > Коллеги, прошу помощи разбором одной проблемы. Предполагаю,
> > что это какая-то очевидная ошибка: то ли я действительно не
> > умею готовить memcpy(), то ли где-то в программе есть ошибки
> > при работе с памятью, которые влияют косвенно (может в данном
> > случае такое быть?).
> > Итак, у меня есть вот такой код
>
> >> 1460 if (_data.size % 2 && _data.data[8] == 0x04) {
>
> (_data.size % 2) лично я поменял бы на (_data.size & 0x01)
Да, так на порядок быстрее.
> >> 1461 // Uncompressed point (the first 8 bytes is the UKM)
> >> 1462 memcpy (_data.data + 8, _data.data + 9, _data.size - 9);
> >> 1463 _data.size--;
> >> 1464 }
>
> Наверняка какая-нибудь грабля с выравниванием...
Тут ко всему не очевидное поведение компилятора при работе с адресами,
когда их складывают с целыми (много от чего зависит и в ряде случаев
просто на ворнинги можно нарваться). Такой код в любом случае сразу
переписывать на более безопасный, независимо от memcpy()/memmove().
Например, так:
memmove(&_data.data[8], &data.data[9], _data.size - 9); /* если тип
данных [unsigned] char */
--
Best regards,
Leonid Krivoshein.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [devel] memcpy глючит (или я не умею его готовить)
2019-02-22 19:27 ` Leonid Krivoshein
@ 2019-02-22 20:51 ` Vladimir Didenko
2019-02-22 22:48 ` Leonid Krivoshein
0 siblings, 1 reply; 15+ messages in thread
From: Vladimir Didenko @ 2019-02-22 20:51 UTC (permalink / raw)
To: ALT Linux Team development discussions
пт, 22 февр. 2019 г. в 22:29, Leonid Krivoshein:
> 21.02.2019 16:25, Alexey V. Vissarionov пишет:
> > (_data.size % 2) лично я поменял бы на (_data.size & 0x01)
>
> Да, так на порядок быстрее.
Это одинаково. Не надо оптимизировать за компилятор, он с этим и сам
неплохо справляется (иногда, даже чересчур)
>
> Тут ко всему не очевидное поведение компилятора при работе с адресами,
> когда их складывают с целыми (много от чего зависит и в ряде случаев
> просто на ворнинги можно нарваться). Такой код в любом случае сразу
> переписывать на более безопасный, независимо от memcpy()/memmove().
> Например, так:
>
> memmove(&_data.data[8], &data.data[9], _data.size - 9); /* если тип
> данных [unsigned] char */
>
Вы глупость написали. Арифметика указателей и целых чисел вполне
определена и безопасна, если не выходить за границы массива. И еще -
запись p + 8 и &p[8] равносильны согласно стандарту языка C.
--
С уважением,
Владимир.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [devel] memcpy глючит (или я не умею его готовить)
2019-02-22 20:51 ` Vladimir Didenko
@ 2019-02-22 22:48 ` Leonid Krivoshein
2019-02-23 1:21 ` Mikhail Efremov
0 siblings, 1 reply; 15+ messages in thread
From: Leonid Krivoshein @ 2019-02-22 22:48 UTC (permalink / raw)
To: devel
22.02.2019 23:51, Vladimir Didenko пишет:
> пт, 22 февр. 2019 г. в 22:29, Leonid Krivoshein:
>> 21.02.2019 16:25, Alexey V. Vissarionov пишет:
>>> (_data.size % 2) лично я поменял бы на (_data.size & 0x01)
>> Да, так на порядок быстрее.
> Это одинаково. Не надо оптимизировать за компилятор, он с этим и сам
> неплохо справляется (иногда, даже чересчур)
Это может быть одинаково при соблюдении многих "если". А может и не
быть. Лучше писать сразу без надежд на "если".
>> Тут ко всему не очевидное поведение компилятора при работе с адресами,
>> когда их складывают с целыми (много от чего зависит и в ряде случаев
>> просто на ворнинги можно нарваться). Такой код в любом случае сразу
>> переписывать на более безопасный, независимо от memcpy()/memmove().
>> Например, так:
>>
>> memmove(&_data.data[8], &data.data[9], _data.size - 9); /* если тип
>> данных [unsigned] char */
>>
> Вы глупость написали. Арифметика указателей и целых чисел вполне
> определена и безопасна, если не выходить за границы массива. И еще -
> запись p + 8 и &p[8] равносильны согласно стандарту языка C.
И каково же её определение в разных стандартах языка C? А реализация в
разных компиляторах? К примеру, согласно N1570 (6.5.6) над
void-указателями такого не проделаешь, в отличие от gcc, который тоже ни
один стандарт могёт. Кстати, именно с такой арифметикой на более старом
gcc на ворнинги нарывался и всегда их сразу выправлял. Нет, лучше об
этом не думать, а писать сразу так, чтобы работало везде.
--
Best regards,
Leonid Krivoshein.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [devel] memcpy глючит (или я не умею его готовить)
2019-02-22 22:48 ` Leonid Krivoshein
@ 2019-02-23 1:21 ` Mikhail Efremov
2019-02-23 12:28 ` Leonid Krivoshein
0 siblings, 1 reply; 15+ messages in thread
From: Mikhail Efremov @ 2019-02-23 1:21 UTC (permalink / raw)
To: ALT Linux Team development discussions
On Sat, 23 Feb 2019 01:48:30 +0300 Leonid Krivoshein wrote:
> 22.02.2019 23:51, Vladimir Didenko пишет:
> > пт, 22 февр. 2019 г. в 22:29, Leonid Krivoshein:
> >> Тут ко всему не очевидное поведение компилятора при работе с
> >> адресами, когда их складывают с целыми (много от чего зависит и в
> >> ряде случаев просто на ворнинги можно нарваться). Такой код в
> >> любом случае сразу переписывать на более безопасный, независимо от
> >> memcpy()/memmove(). Например, так:
> >>
> >> memmove(&_data.data[8], &data.data[9], _data.size - 9); /* если тип
> >> данных [unsigned] char */
> >>
> > Вы глупость написали. Арифметика указателей и целых чисел вполне
> > определена и безопасна, если не выходить за границы массива. И еще -
> > запись p + 8 и &p[8] равносильны согласно стандарту языка C.
Более того, можно еще и &8[p] написать, совершенно корректная запись с
точки зрения синтаксиса языка :). Другое дело, что за такое в реальном
коде надо руки отрывать сразу.
> И каково же её определение в разных стандартах языка C? А реализация
> в разных компиляторах? К примеру, согласно N1570 (6.5.6) над
В стандарте арифметика указателей описана вполне ясно.
> void-указателями такого не проделаешь, в отличие от gcc, который тоже
> ни один стандарт могёт.
Я не понял этой фразы и сравнения указателей с gcc. При чем тут
указатель на void? Размер объекта в этом случае не известен, разумеется
арифметика не работает.
> Кстати, именно с такой арифметикой на более
> старом gcc на ворнинги нарывался и всегда их сразу выправлял. Нет,
> лучше об этом не думать, а писать сразу так, чтобы работало везде.
Полагаю, что предупреждения были о чем-то другом.
--
WBR, Mikhail Efremov
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [devel] memcpy глючит (или я не умею его готовить)
2019-02-23 1:21 ` Mikhail Efremov
@ 2019-02-23 12:28 ` Leonid Krivoshein
2019-02-23 12:55 ` Alexey V. Vissarionov
0 siblings, 1 reply; 15+ messages in thread
From: Leonid Krivoshein @ 2019-02-23 12:28 UTC (permalink / raw)
To: devel
[-- Attachment #1: Type: text/plain, Size: 5050 bytes --]
23.02.2019 04:21, Mikhail Efremov пишет:
> On Sat, 23 Feb 2019 01:48:30 +0300 Leonid Krivoshein wrote:
>> 22.02.2019 23:51, Vladimir Didenko пишет:
>>> пт, 22 февр. 2019 г. в 22:29, Leonid Krivoshein:
>>>> Тут ко всему не очевидное поведение компилятора при работе с
>>>> адресами, когда их складывают с целыми (много от чего зависит и в
>>>> ряде случаев просто на ворнинги можно нарваться). Такой код в
>>>> любом случае сразу переписывать на более безопасный, независимо от
>>>> memcpy()/memmove(). Например, так:
>>>>
>>>> memmove(&_data.data[8], &data.data[9], _data.size - 9); /* если тип
>>>> данных [unsigned] char */
>>>>
>>> Вы глупость написали. Арифметика указателей и целых чисел вполне
>>> определена и безопасна, если не выходить за границы массива. И еще -
>>> запись p + 8 и &p[8] равносильны согласно стандарту языка C.
> Более того, можно еще и &8[p] написать, совершенно корректная запись с
> точки зрения синтаксиса языка :). Другое дело, что за такое в реальном
> коде надо руки отрывать сразу.
Согласен. Такого я не предлагал.
>> И каково же её определение в разных стандартах языка C? А реализация
>> в разных компиляторах? К примеру, согласно N1570 (6.5.6) над
> В стандарте арифметика указателей описана вполне ясно.
В актуальном, что я привёл? Или в каком-то другом?
Раз возникают такие странные споры на почти пустом месте, значит, ясно
не для всех одинаково.
>> void-указателями такого не проделаешь, в отличие от gcc, который тоже
>> ни один стандарт могёт.
> Я не понял этой фразы и сравнения указателей с gcc. При чем тут
> указатель на void? Размер объекта в этом случае не известен, разумеется
> арифметика не работает.
Моя фраза прозвучала вполне чётко: в этом месте gcc и действующий
стандарт расходятся. gcc допускает сложение целого числа с указателем на
void, принимая размер указываемого объекта равным одному байту.
$ gcc -o v1 -DUSEVOID examle.c
$ gcc -o v2 -DUSEVOID -DSAFEPTR examle.c
examle.c: In function ‘main’:
examle.c:21:12: warning: dereferencing ‘void *’ pointer
func(&base[6]);
^
examle.c:21:7: warning: taking address of expression of type ‘void’
func(&base[6]);
^
Пример во вложении. Теперь понятно, почему предлагаемая запись более
безопасна? Вашу запись gcc проглотит, даже не поперхнувшись. В примере
ещё и второе объяснение по объектам размером более одного байта:
$ gcc -o i1 examle.c
$ gcc -o i2 -DSAFEPTR examle.c
./i1
24
6
$ ./i2
24
6
Вы прибавляете к адресу целое число, которое является чем? Разницей в
адресах или индексах? Я вот стандарты не штудирую, в голове их не держу,
и в моей привычке такой записи никаких неоднозначных толкований быть не
может. Просто пишите так, и не ошибётесь никогда.
>> Кстати, именно с такой арифметикой на более
>> старом gcc на ворнинги нарывался и всегда их сразу выправлял. Нет,
>> лучше об этом не думать, а писать сразу так, чтобы работало везде.
> Полагаю, что предупреждения были о чем-то другом.
Может быть, не помню уже. Попробуйте откатить этот commit:
http://git.altlinux.org/gears/p/propagator.git?p=propagator.git;a=commitdiff;h=d2866d5d21fd1fe31ebcbbf82490fbbb25de834b
Более подходящего примера сходу не нахожу.
--
Best regards,
Leonid Krivoshein.
[-- Attachment #2: examle.c --]
[-- Type: text/x-csrc, Size: 367 bytes --]
#include <stdio.h>
#if defined(USEVOID)
#define TYPE void
#else
#define TYPE int
#endif
TYPE *base;
void func(TYPE* ptr) {
#if !defined(USEVOID)
printf("%ld\n", ((void*)ptr) - ((void*)base));
#endif
printf("%ld\n", ptr - base);
}
int main(int argc, char argv[]) {
base = &argc;
#if defined(SAFEPTR)
func(&base[6]);
#else
func(base + 6);
#endif
return 0;
}
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [devel] memcpy глючит (или я не умею его готовить)
2019-02-23 12:28 ` Leonid Krivoshein
@ 2019-02-23 12:55 ` Alexey V. Vissarionov
2019-02-23 13:08 ` Leonid Krivoshein
2019-02-24 11:06 ` Mikhail Efremov
0 siblings, 2 replies; 15+ messages in thread
From: Alexey V. Vissarionov @ 2019-02-23 12:55 UTC (permalink / raw)
To: ALT Linux Team development discussions
On 2019-02-23 15:28:44 +0300, Leonid Krivoshein wrote:
>>> void-указателями такого не проделаешь, в отличие от gcc, который
>>> тоже >>> ни один стандарт могёт.
>> Я не понял этой фразы и сравнения указателей с gcc. При чем тут
>> указатель на void? Размер объекта в этом случае не известен,
>> разумеется арифметика не работает.
Арихметика работает независимо от. Например, конструкцию вида
void *x; int y = x[1];
компилятор пошлет по азимуту, и правильно сделает. Но при этом
void *x; int y = x+123;
не вызовет у компилятора никаких эмоций и превратится (на писюшатине)
в самый обычный lea. Почему? Потому что это обычное сложение, а как
потом будет использоваться результат - уже забота не компилятора, а
программиста.
Если что, я такие конструкции регулярно использую, когда пишу для
контроллеров.
> Вы прибавляете к адресу целое число, которое является чем?
> Разницей в адресах или индексах?
sizeof(void) - это сколько? :-)
--
Alexey V. Vissarionov
gremlin ПРИ altlinux ТЧК org; +vii-cmiii-ccxxix-lxxix-xlii
GPG: 0D92F19E1C0DC36E27F61A29CD17E2B43D879005 @ hkp://keys.gnupg.net
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [devel] memcpy глючит (или я не умею его готовить)
2019-02-23 12:55 ` Alexey V. Vissarionov
@ 2019-02-23 13:08 ` Leonid Krivoshein
2019-02-23 14:46 ` Alexey Tourbin
2019-02-24 11:06 ` Mikhail Efremov
1 sibling, 1 reply; 15+ messages in thread
From: Leonid Krivoshein @ 2019-02-23 13:08 UTC (permalink / raw)
To: devel
23.02.2019 15:55, Alexey V. Vissarionov пишет:
> On 2019-02-23 15:28:44 +0300, Leonid Krivoshein wrote:
>
> >>> void-указателями такого не проделаешь, в отличие от gcc, который
> >>> тоже >>> ни один стандарт могёт.
> >> Я не понял этой фразы и сравнения указателей с gcc. При чем тут
> >> указатель на void? Размер объекта в этом случае не известен,
> >> разумеется арифметика не работает.
>
> Арихметика работает независимо от. Например, конструкцию вида
>
> void *x; int y = x[1];
>
> компилятор пошлет по азимуту, и правильно сделает. Но при этом
>
> void *x; int y = x+123;
>
> не вызовет у компилятора никаких эмоций
А по-моему здесь будет ворнинг. Но можно проверить.
> и превратится (на писюшатине)
> в самый обычный lea. Почему? Потому что это обычное сложение, а как
> потом будет использоваться результат - уже забота не компилятора, а
> программиста.
>
> Если что, я такие конструкции регулярно использую, когда пишу для
> контроллеров.
В любом случае я бы такие рисковые конструкции не использовал.
> > Вы прибавляете к адресу целое число, которое является чем?
> > Разницей в адресах или индексах?
>
> sizeof(void) - это сколько? :-)
Вчера было 1 (для gcc). Но тогда это ответ неверный. Потому что,
согласно стандарту, разница должна быть в индексах, а не в байтах. И
согласно ему же результат такого сложения с void* не определён. А в gcc
это будет эквивалентно char* + int.
--
Best regards,
Leonid Krivoshein.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [devel] memcpy глючит (или я не умею его готовить)
2019-02-23 13:08 ` Leonid Krivoshein
@ 2019-02-23 14:46 ` Alexey Tourbin
2019-02-23 15:02 ` Leonid Krivoshein
0 siblings, 1 reply; 15+ messages in thread
From: Alexey Tourbin @ 2019-02-23 14:46 UTC (permalink / raw)
To: ALT Linux Team development discussions
On Sat, Feb 23, 2019 at 4:09 PM Leonid Krivoshein <klark.devel@gmail.com> wrote:
> 23.02.2019 15:55, Alexey V. Vissarionov пишет:
> > On 2019-02-23 15:28:44 +0300, Leonid Krivoshein wrote:
> >
> > >>> void-указателями такого не проделаешь, в отличие от gcc, который
> > >>> тоже >>> ни один стандарт могёт.
> > >> Я не понял этой фразы и сравнения указателей с gcc. При чем тут
> > >> указатель на void? Размер объекта в этом случае не известен,
> > >> разумеется арифметика не работает.
> >
> > Арихметика работает независимо от. Например, конструкцию вида
> >
> > void *x; int y = x[1];
> >
> > компилятор пошлет по азимуту, и правильно сделает. Но при этом
> >
> > void *x; int y = x+123;
> >
> > не вызовет у компилятора никаких эмоций
>
> А по-моему здесь будет ворнинг. Но можно проверить.
-Wpointer-arith
клуб знатоков
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [devel] memcpy глючит (или я не умею его готовить)
2019-02-23 14:46 ` Alexey Tourbin
@ 2019-02-23 15:02 ` Leonid Krivoshein
0 siblings, 0 replies; 15+ messages in thread
From: Leonid Krivoshein @ 2019-02-23 15:02 UTC (permalink / raw)
To: devel
23.02.2019 17:46, Alexey Tourbin пишет:
> On Sat, Feb 23, 2019 at 4:09 PM Leonid Krivoshein <klark.devel@gmail.com> wrote:
>> 23.02.2019 15:55, Alexey V. Vissarionov пишет:
>>> void *x; int y = x+123;
>>>
>>> не вызовет у компилятора никаких эмоций
>> А по-моему здесь будет ворнинг. Но можно проверить.
> -Wpointer-arith
> клуб знатоков
Без этого ключика -- один ворнинг, а с ним -- два.
Но ключик -- да, как раз об этом расширении gcc.
клуб въедливых практиков)
--
Best regards,
Leonid Krivoshein.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [devel] memcpy глючит (или я не умею его готовить)
2019-02-23 12:55 ` Alexey V. Vissarionov
2019-02-23 13:08 ` Leonid Krivoshein
@ 2019-02-24 11:06 ` Mikhail Efremov
2019-02-24 16:22 ` [devel] gcc pointer arithmetics Dmitry V. Levin
1 sibling, 1 reply; 15+ messages in thread
From: Mikhail Efremov @ 2019-02-24 11:06 UTC (permalink / raw)
To: ALT Linux Team development discussions
On Sat, 23 Feb 2019 15:55:21 +0300 Alexey V. Vissarionov wrote:
> On 2019-02-23 15:28:44 +0300, Leonid Krivoshein wrote:
>
> >>> void-указателями такого не проделаешь, в отличие от gcc, который
> >>> тоже >>> ни один стандарт могёт.
> >> Я не понял этой фразы и сравнения указателей с gcc. При чем тут
> >> указатель на void? Размер объекта в этом случае не известен,
> >> разумеется арифметика не работает.
>
> Арихметика работает независимо от. Например, конструкцию вида
>
> void *x; int y = x[1];
>
> компилятор пошлет по азимуту, и правильно сделает. Но при этом
>
> void *x; int y = x+123;
>
> не вызовет у компилятора никаких эмоций и превратится (на писюшатине)
> в самый обычный lea. Почему? Потому что это обычное сложение, а как
> потом будет использоваться результат - уже забота не компилятора, а
> программиста.
>
> Если что, я такие конструкции регулярно использую, когда пишу для
> контроллеров.
Ну, я видимо не использовал, поэтому не помню, спасибо.
Вообще логично, до того как в языке появился void * обычно использовали
char * для этих целей.
--
WBR, Mikhail Efremov
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [devel] gcc pointer arithmetics
2019-02-24 11:06 ` Mikhail Efremov
@ 2019-02-24 16:22 ` Dmitry V. Levin
0 siblings, 0 replies; 15+ messages in thread
From: Dmitry V. Levin @ 2019-02-24 16:22 UTC (permalink / raw)
To: ALT Devel discussion list
[-- Attachment #1: Type: text/plain, Size: 1416 bytes --]
On Sun, Feb 24, 2019 at 02:06:56PM +0300, Mikhail Efremov wrote:
> On Sat, 23 Feb 2019 15:55:21 +0300 Alexey V. Vissarionov wrote:
> > On 2019-02-23 15:28:44 +0300, Leonid Krivoshein wrote:
> >
> > >>> void-указателями такого не проделаешь, в отличие от gcc, который
> > >>> тоже >>> ни один стандарт могёт.
> > >> Я не понял этой фразы и сравнения указателей с gcc. При чем тут
> > >> указатель на void? Размер объекта в этом случае не известен,
> > >> разумеется арифметика не работает.
> >
> > Арихметика работает независимо от. Например, конструкцию вида
> >
> > void *x; int y = x[1];
> >
> > компилятор пошлет по азимуту, и правильно сделает. Но при этом
> >
> > void *x; int y = x+123;
> >
> > не вызовет у компилятора никаких эмоций и превратится (на писюшатине)
> > в самый обычный lea. Почему? Потому что это обычное сложение, а как
> > потом будет использоваться результат - уже забота не компилятора, а
> > программиста.
> >
> > Если что, я такие конструкции регулярно использую, когда пишу для
> > контроллеров.
>
> Ну, я видимо не использовал, поэтому не помню, спасибо.
> Вообще логично, до того как в языке появился void * обычно использовали
> char * для этих целей.
Это gcc extension, причём довольно старый.
https://gcc.gnu.org/onlinedocs/gcc-8.3.0/gcc/Pointer-Arith.html
https://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_4.html#SEC78
--
ldv
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2019-02-24 16:22 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-21 13:17 [devel] memcpy глючит (или я не умею его готовить) Paul Wolneykien
2019-02-21 13:22 ` Vladimir Didenko
2019-02-21 13:28 ` Paul Wolneykien
2019-02-21 13:25 ` Alexey V. Vissarionov
2019-02-22 19:27 ` Leonid Krivoshein
2019-02-22 20:51 ` Vladimir Didenko
2019-02-22 22:48 ` Leonid Krivoshein
2019-02-23 1:21 ` Mikhail Efremov
2019-02-23 12:28 ` Leonid Krivoshein
2019-02-23 12:55 ` Alexey V. Vissarionov
2019-02-23 13:08 ` Leonid Krivoshein
2019-02-23 14:46 ` Alexey Tourbin
2019-02-23 15:02 ` Leonid Krivoshein
2019-02-24 11:06 ` Mikhail Efremov
2019-02-24 16:22 ` [devel] gcc pointer arithmetics Dmitry V. Levin
ALT Linux Team development discussions
This inbox may be cloned and mirrored by anyone:
git clone --mirror http://lore.altlinux.org/devel/0 devel/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 devel devel/ http://lore.altlinux.org/devel \
devel@altlinux.org devel@altlinux.ru devel@lists.altlinux.org devel@lists.altlinux.ru devel@linux.iplabs.ru mandrake-russian@linuxteam.iplabs.ru sisyphus@linuxteam.iplabs.ru
public-inbox-index devel
Example config snippet for mirrors.
Newsgroup available over NNTP:
nntp://lore.altlinux.org/org.altlinux.lists.devel
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git