[devel] [SCM] packages/apt: heads/rework-dynamic-mmap

Ivan Zakharyaschev imz на altlinux.org
Ср Фев 12 05:14:07 MSK 2020


> Если арифметика с 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


Подробная информация о списке рассылки Devel