ALT Linux Team development discussions
 help / color / mirror / Atom feed
* [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