什么可移植性问题与为指针字节级别的访问在C中有关?

问题描述:

目的

我写一个小型图书馆的大型项目,该项目提供的malloc / realloc的/免费包装,功能以及一个函数,它可以告诉你的类型,其与否参数(无效* )对应于生活(尚未释放)内存分配和磁带库的包装,功能管理。让我们将此功能 isgood_memory

I am writing a small library for a larger project which supplies malloc/realloc/free wrapper-functions as well as a function which can tell you whether or not its parameter (of type void *) corresponds to live (not yet freed) memory allocated and managed by the library's wrapper-functions. Let's refer to this function as isgood_memory.

在内部,图书馆保持一个哈希表,以确保搜索按 isgood_memory 执行是相当快的。哈希表维持指针的的(类型的元素无效* ),以使搜索成为可能。显然,值相加,并从哈希表中删除,以保持它的最新与什么什么已被分配和被释放,分别

Internally, the library maintains a hash-table to ensure that the search performed by isgood_memory is reasonably fast. The hash-table maintains pointer values (elements of type void *) to make the search possible. Clearly, values are added and removed from the hash-table to keep it up-to-date with what has been allocated and what has been freed, respectively.

该库的便携性是我最大的担忧。它被设计为只承担一大部分符合C90(ISO / IEC 9899:1990)。环境......仅此而已

The portability of the library is my biggest concern. It has been designed to assume only a mostly-compliant C90 (ISO/IEC 9899:1990) environment... nothing more.

问题

由于便携性是我最关心的问题,我不能假设的sizeof(无效*)==的sizeof(X)的哈希函数。因此,我已使出处理值逐字节就好像它是一个字符串。要做到这一点,散列函数看起来有点像:

Since portability is my biggest concern, I couldn't assume that sizeof(void *) == sizeof(X) for the hash-function. Therefore, I have resorted to treating the value byte-by-byte as if it were a string. To accomplish this, the hash function looks a little like:

static size_t hashit(void *ptrval)
{
    size_t i = 0, h = 0;
    union {
        void *ptrval;
        unsigned char string[sizeof(void *)];
    } ptrstr;

    ptrstr.ptrval = ptrval;

    for (; i < sizeof(void *); ++i) {
        size_t byte = ptrstr.string[i];

        /* Crazy operations here... */
    }

    return (h);
}

什么便携性的担忧做任何你有这种特殊的片段?我将在访问中遇到任何时​​髦的对齐问题 ptrval 逐字节?

您可以访问的数据类型为unsigned char类型的数组,你在这里做。主要的可移植性问题,我看到可能发生在平台上,其中的位模式,标识一个特定位置不是唯一的。 - 在这种情况下,你可能会得到等于散列该比较不同的位置的指针,因为这些位模式是不同的

You are allowed to access a data type as an array of unsigned char, as you do here. The major portability issue that I see could occur on platforms where the bit-pattern identifying a particular location is not unique - in that case, you might get pointers that compare equal hashing to different locations because the bit patterns were different.

为什么能将它们有什么不同?那么,对于一件事,大多数C数据类型允许包含填充位不参与价值。其中所含的指针,例如填充比特的平台可以有两个指针仅在填充比特指向同一位置不同。 (例如,操作系统可能会使用一些指针位以指示指针的能力,而不仅仅是物理地址)。另一个例子是从DOS,初期其中远指针由段的远存储器模型:偏移,以及相邻的段重叠,以使段:偏移可以指向相同的位置段+ 1:偏移-X

Why could they be different? Well, for one thing, most C data types are allowed to contain padding bits that don't participate in the value. A platform where pointers contained such padding bits could have two pointers that differed only in the padding bits point to the same location. (For example, the OS might use some pointer bits to indicate capabilities of the pointer, not just physical address.) Another example is the far memory model from the early days of DOS, where far pointers consisted of segment:offset, and the adjacent segments overlapped, so that segment:offset could point to the same location as segment+1:offset-x.

所有今天说,在共同使用大多数平台,该位模式指向给定的位置确实是独一无二的。所以,你的code将广泛移植,即使它是不太可能严格符合。

All that said, on most platforms in common use today, the bit pattern pointing to a given location is indeed unique. So your code will be widely portable, even though it is unlikely to be strictly conforming.