4

我正在研究将面向对象语言转换为 C 以优化 puproses,但我遇到了设计问题。

考虑为转换器提供以下伪语言类:

class C {
    int a;
    double b;
    int c;

    constructor C(int value) {
        this.a = value;
        this.b = this.a / 10.0;
        this.c = 0;
    }

    void say() {
        print(this.b);
    }
}

直截了当地说,我们可以在 C 中将这个类表示为这样的结构(跳过错误检查):

typedef struct {
    int a;
    double b;
    int c;
} _class_C;

_class_C* _ctor_C(int value) {
    this = malloc(sizeof(_class_C));

    this->a = value;
    this->b = this->a / 10.0;
    this->c = 0;

    return this;
}

void _method_C_say(_class_C *this) {
    printf("%.2f", this->b);
}

void _dtor_C(_class_C *this) {
    free(this);
}

这个解决方案受到 C 编译器所绑定的承诺的影响——不要在结构中添加、删除或更改字段的顺序。因此,尽管没有使用事实字段ac但它们会使代码膨胀。

如何实现“无序字段”行为?如果我只有一个 static C,它可以写成如下:

int _staticfield_C_a;
double _staticfield_C_b;
int _staticfield_C_c;

void _ctor_C(int value) {
    _staticfield_C_a = value;
    _staticfield_C_b = _staticfield_C_a / 10.0;
    _staticfield_C_c = 0;
}

void _staticmethod_C_say() {
    printf("%.2f", _staticfield_C_b);
}

因此编译器可以将冗余或未使用的字段优化到 sole ,但是当可以动态实例化_staticfield_C_b时我应该使用什么解决方案,而且我根本不介意字段的顺序、内存布局和代码的可读性?C

更新:应该注意的是,我并没有试图强制编译器使用structs来做魔术,我想要一些替换它们的行为就像 struct 具有无序字段 - 就像我在静态示例中提供的那样,无论可读性级别如何.

更新:评论中有一种流行的观点认为我的问题与转换器本身的设计有关,比如我为它选择了错误的范式或语言。Converter 本身是用 Python 编写的,它获取通用的面向对象程序的源代码,对其进行处理并输出等效的 C 代码进行编译,因此您可以将其视为跨语言编译器。我很高兴向我解释我应该在哪里以及如何使用结构,但在这种情况下,我需要一些魔法帮助来简化优化:)

4

2 回答 2

4

听起来您正在尝试让编译器(或链接器 - 您提到的“删除未使用的对象”优化实际上在那里完成)来自动为您检测未使用的结构字段。不能,因为不可能。这是一个全局优化——你需要知道在宇宙中任何地方都没有引用给定字段的代码。但是,如果代码将来会动态绑定到引用该字段的某些内容(代码不是当前链接的一部分)怎么办?用相同的头文件编译一个库怎么样。鉴于编译器不知道如何使用它,编译器应该制作多大的结构?

如果你想做这个优化,恐怕你得自己做。C 语言没有可用的工具。

于 2012-07-13T15:51:44.987 回答
0

您是否考虑Unions过作为替代方案Structs

如果您一次只使用一个字段并且担心内存问题,那么这是完美的数据结构。

于 2012-07-13T14:03:10.057 回答