[devel] [SCM] packages/apt: heads/rework-dynamic-mmap
Dmitry V. Levin
ldv на altlinux.org
Ср Фев 12 11:47:41 MSK 2020
On Wed, Feb 12, 2020 at 05:14:07AM +0300, Ivan Zakharyaschev wrote:
> > Если арифметика с void* в cxx не поддерживается, значит, она не
> > использовалась, и фраза "We do not want to rely on non-standard
> > void*-arithmetic" просто сбивает с толку.
> >
> > C-style cast - это не арифметика с указателями.
>
> Переписал так эти места:
>
> commit 99994eb9e7580e9dd0014fe9a37bc68a0b9fff5e
> Author: Ivan Zakharyaschev <imz на altlinux.org>
> Date: Wed Jan 29 04:41:13 2020 +0300
>
> use the safer C++-style static_cast instead of a C-style cast (from void*)
>
> What is happening here
> (a commentary clarifying the code, not this particular stylistic change):
>
> Map->RawAllocate() returns the index in an array of bytes (i.e., of char;
> no matter whether they are (un)signed); therefore, we cast the base
> pointer to the corresponding type, so that the pointer arithmetic
> gives a pointer to the beginning of the allocated space.
>
> If you wonder why use a cast at all here, then note that Map->Data()
> returns a void* value, and pointer arithmetic on void* is not allowed in C++
> (and is a non-standard extension in GNU C, not GNU C++, which would actually
> give the same result as our code).
>
> diff --git a/apt/apt-pkg/pkgcachegen.cc b/apt/apt-pkg/pkgcachegen.cc
> index 070c0f040..16d3592e9 100644
> --- a/apt/apt-pkg/pkgcachegen.cc
> +++ b/apt/apt-pkg/pkgcachegen.cc
> @@ -882,7 +882,7 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress,
> {
> // Preload the map with the source cache
> FileFd SCacheF(SrcCacheFile,FileFd::ReadOnly);
> - if (SCacheF.Read((unsigned char *)Map->Data() + Map->RawAllocate(SCacheF.Size()),
> + if (SCacheF.Read(static_cast<char *>(Map->Data()) + Map->RawAllocate(SCacheF.Size()),
> SCacheF.Size()) == false)
> return false;
>
>
> commit e1db00879ce008555a6fbc3195b3cd92e6c25eb9
> Author: Ivan Zakharyaschev <imz на altlinux.org>
> Date: Wed Jan 29 05:02:13 2020 +0300
>
> rigorously compute HeaderP as the pointer to the beginning of Map
>
> The old code expected that the first call to Map.RawAllocate() would
> give the pointer to the very beginning of Map, i.e., the same as
> Map.Data().
>
> We rewrite this code without such presupposition: no matter what the
> logic behind Map.RawAllocate() will ever be, we'll actually get the
> pointer to the space which is being "allocated" by this call inside
> Map.
>
> We use the safer C++-style static_cast (from void*) where possible.
>
> What is happening here with the pointer arithmetic:
>
> Map->RawAllocate() returns the index in an array of bytes (i.e., of char);
> therefore, we cast the base pointer to the corresponding type, so that
> the pointer arithmetic gives the correct pointer to the beginning of the
> "allocated" space.
>
> If you wonder why use a cast at all here, then note that Map->Data()
> returns a void* value, and pointer arithmetic on void* is not allowed in C++
> (and is a non-standard extension in GNU C, not GNU C++, which would actually
> give the same result as our code).
>
> diff --git a/apt/apt-pkg/pkgcachegen.cc b/apt/apt-pkg/pkgcachegen.cc
> index 16d3592e9..8bf5ed639 100644
> --- a/apt/apt-pkg/pkgcachegen.cc
> +++ b/apt/apt-pkg/pkgcachegen.cc
> @@ -54,9 +54,10 @@ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) :
>
> if (Map.Size() == 0)
> {
> + const auto idxBeginning = Map.RawAllocate(sizeof(pkgCache::Header));
> +
> // Setup the map interface..
> - Cache.HeaderP = (pkgCache::Header *)Map.Data();
> - Map.RawAllocate(sizeof(pkgCache::Header));
> + Cache.HeaderP = reinterpret_cast<pkgCache::Header *>(static_cast<char *>(Map.Data()) + idxBeginning);
> Map.UsePools(*Cache.HeaderP->Pools,sizeof(Cache.HeaderP->Pools)/sizeof(Cache.HeaderP->Pools[0]));
>
> // Starting header
Теперь понятно, спасибо.
--
ldv
Подробная информация о списке рассылки Devel