Is it legal to implement inheritance in C through cast pointers between one structure, which is a subset of the other, not the first member?

Now I know that I can implement inheritance by hovering over structthe type of the first element of this struct.

However, as a learning experience, I began to wonder if it is possible to implement inheritance in a slightly different way.

Is this code legal?

#include <stdio.h>
#include <stdlib.h>

struct base
{
    double some;
    char space_for_subclasses[];
};

struct derived
{
    double some;
    int value;
};

int main(void) {
    struct base *b = malloc(sizeof(struct derived));
    b->some = 123.456;
    struct derived *d = (struct derived*)(b);
    d->value = 4;
    struct base *bb = (struct base*)(d);
    printf("%f\t%f\t%d\n", d->some, bb->some, d->value);
    return 0;
}

This code seems to give the desired results , but as we know, this far from proves that it is not UB.

, , , , , . , , , , , - UB .

  • ?
  • , ?
  • char space_for_subclasses[];? , -, ,
+3
2

, struct sockaddr, . :

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>

struct base
{
    double some;
    char space_for_subclasses[];
};
struct derived
{
    double some;
    int value;
};

double test(struct base *a, struct derived *b)
{
    a->some = 1.0;
    b->some = 2.0;
    return a->some;
}

int main(void)
{
    void *block = malloc(sizeof(struct derived));
    if (!block) {
        perror("malloc");
        return 1;
    }
    double x = test(block, block);
    printf("x=%g some=%g\n", x, *(double *)block);
    return 0;
}

a->some b->some , x=2.0 some=2.0, ( , , , test ), x=1.0 some=2.0.

, a->some b->some . . http://blog.regehr.org/archives/1466 , .

+1

, §6.2.6.1/P5,

. lvalue, , undefined. [...]

, space_for_subclasses char (array-decays-to-pointer), , .


,

char space_for_subclasses[];?

, .

§6.7.2.1/P18,

; . , . , , , , , . , . ( ->) , ( ) , , , ( ), , , ; , . , , , undefined, , .

, , undefined . ( ) value, .

+4

Source: https://habr.com/ru/post/1678117/


All Articles