Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
143 views
in Technique[技术] by (71.8m points)

c - What does it mean that void* has the same representation and memory alignment as char*?

I've been reading some articles about void* type pointers and found this requirement from the Standard.

6.2.5.27:

A pointer to void shall have the same representation and alignment requirements as a pointer to a character type.39) Similarly, pointers to qualified or unqualified versions of compatible types shall have the same representation and alignment requirements.

I see that the Standard does not guarantee all pointer types have the same length, so the bottom line here is that a void* pointer has the same length and alignment rules as char*, right?

What I don't get is the footnote 39), which says

The same representation and alignment requirements are meant to imply interchangeability as arguments to functions, return values from functions, and members of unions.

My questions are:

  1. What does it mean by "interchangeability"? Does it say the argument and the return values of a function void* Func(void*) can both be char*?

  2. If so, is it an implicit conversion made by the compiler?

  3. And what is it about the members of unions? I really don't get a grasp of the meaning of this. Can anyone give me a simple example?

question from:https://stackoverflow.com/questions/65651699/what-does-it-mean-that-void-has-the-same-representation-and-memory-alignment-as

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

In C any data pointer can be passed to a function that expects a void * and a void * can be stored to any pointer type. There is an implicit conversion between void * and other pointer types. But this does not mean that this conversion is harmless. On some architectures where void * and int * have a different representation, converting from int * to void * and then back to int * is specified as producing the same pointer value, but the converse does not hold: converting a void * to int * and back to void * may produce a different value, especially if the void * was not obtained by converting an int *.

Interchangeability means that this implicit conversion does not change the representation of the pointer. the conversion can be operated both ways successfully: converting a character pointer to void * and back produces the same pointer and vice versa.

Here is an example:

#include <assert.h>
#include <stdio.h>
#include <string.h>

int main() {
    char *s = "abc";
    char *s1;
    void *p;
    void *p1;

    assert(sizeof(p) == sizeof(s));
    memcpy(&p, &s, sizeof(p));
    p1 = s;
    assert(p == p1);
    memcpy(&s1, &p1, sizeof(s1));
    assert(s == s1);
    return 0;
}

Note however that this does not imply that !memcmp(&p1, &s, sizeof(p1)) because pointers could have padding bits. Neither can you violate the strict aliasing rule by casting through a void *:

  • float f = 1.0; unsigned int i = *(int *)(void *)&f' incorrect.
  • float f = 1.0; unsigned int i; memcpy(&i, &f, sizeof(i)); correct if sizeof(int) == sizeof(float) but may produce a trap value.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.9k users

...