From: Leonid Krivoshein <klark.devel@gmail.com> To: devel@lists.altlinux.org Subject: Re: [devel] memcpy глючит (или я не умею его готовить) Date: Sat, 23 Feb 2019 15:28:44 +0300 Message-ID: <8caf2604-0d15-08c4-5e1a-672fad601818@gmail.com> (raw) In-Reply-To: <20190223012117.79c39033@sem-notebook> [-- 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; }
next prev parent reply other threads:[~2019-02-23 12:28 UTC|newest] Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-02-21 13:17 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 [this message] 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
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=8caf2604-0d15-08c4-5e1a-672fad601818@gmail.com \ --to=klark.devel@gmail.com \ --cc=devel@lists.altlinux.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
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