Reducing the size of returned/passed data structures in C
我正在麻省理工学院在线学习操作系统课程,我完成了第一个作业http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-828-operating-system-engineering-fall-2012/assignments/mit6 f12 ou assignment1.pdfb,但令我惊讶的是,他们如何返回数据结构,如何使用数据结构,并返回urn一个较小的数据结构,要使用它,只需将其重新转换。我看到它可以优化代码,但这是安全的吗?这是好的做法吗?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #include <stdio.h> #include <string.h> #include <stdlib.h> struct small { int n ; }; struct big { int n ; char * string ; }; struct small* f() { struct big* x = malloc(sizeof(struct big)); x->n = 'X'; x->string = strdup("Nasty!"); return (struct small*) x ; } int main(int argc, char *argv[]) { struct big *y = (struct big*)f(); printf("%s ",y->string); } |
编辑1:这是麻省理工学院的链接,我只是用自己的代码复制了这个想法。http://ocw.mit.edu/courses/electrical engineering and computer science/6-828-operating-system-engineering-fall-2012/assignments/sh.c
没有返回结构,只返回指向结构的指针。指针包含实际对象所在内存的地址。(在这种情况下,它是用
该代码是合法的,并定义了语义。N1570草案的6.3.2.3/7表示
A pointer to an object type may be converted to a pointer to a
different object type. If the resulting pointer is not correctly
aligned for the referenced type, the behavior is undefined. [does not apply here. -ps]
Otherwise, when converted back again, the result shall compare equal
to the original pointer.
请注意,结构可能完全不相关(第一个数据元素不需要是相同的类型)。这种类型甚至可以是像
如果由于别名问题而通过错误类型(不是)的指针访问对象,则问题可能不同。
要回答您的问题:
Is it safe?
显然不是。只需将指针的类型转换为其他类型,只有当您确信它是正确的类型时,才应该这样做。
但是,如果你知道,一切都很好。
Is it good practice?
不,不是这个形状。
有时用C语言以类似的方式进行面向对象编程(比较cpython的
1 2 3 4 5 6 7 8 | struct obj_type { const char* name; size_t length; // this is important so that you can copy the object later on without knowing its insides }; struct obj_base { obj_type* type; }; |
因为可以保证在C中,指向结构的指针指向其第一个元素的地址,所以可以使用在此基础上构建的其他对象:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | struct more_complex_object { obj_type* type; int value; }; ... int main() { obj_type *more_complex_object_type = malloc(sizeof(obj_type)); more_complex_object_type->name ="A more complex object type"; more_complex_object_type->length = sizeof(more_complex_object); more_complex_object *obj = malloc(more_complex_object_type->length); obj->type = more_complex_object_type; obj->value = 10; ... //let's now use it as a simple instance of the"super" object obj_base* just_an_object = (obj_base*)more_complex_object; //when we copy things, we make sure to copy the full length: obj_base* target = malloc(sizeof(more_complex_object)); memcpy(target, just_an_object, just_an_object->type->length); //now, when handling an object, we can check its type if(just_an_object->type == more_complex_object_type) { more_complex_object *my_obj = (more_complex_object)just_an_object; printf("value: %d ", my_obj->value); } } |
是的,它是安全的,只要您的编译器遵循C标准
为什么GCC不优化结构?
但不,我不认为这是一个好的做法。
良好的实践是相对的,不应该作为一个规则来使用。如果要用C模拟OO继承行为,则需要使用此构造。