* [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: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: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: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