【发布时间】:2011-03-18 08:53:54
【问题描述】:
这是一个大问题,所以让我先解决一些问题:
- 让我们忽略一些 C++ 功能无法在 C 中实现的事实(例如,支持链接到的任何全局静态对象的 pre-main 初始化)。
- 这是一个关于理论上可行的思想实验。请不要写信说这有多难(我知道),或者我应该做 X。这不是一个实际问题,而是一个有趣的理论问题。 :)
问题是:理论上是否有可能将 C++ 或 C99 编译为 C89 并且与原始源代码一样可移植?
Cfront 和 Comeau C/C++ 已经将 C++ 编译为 C。但是,据 Comeau 的销售人员称,对于 Comeau,他们生产的 C 不是便携式的。我自己没有使用过 Comeau 编译器,但我推测造成这种情况的原因是:
- INT_MAX、offsetof()等宏已经被扩展,它们的扩展是平台特定的。
-
#ifdef等条件编译已经解决。
我的问题是这些问题是否可能以一种强有力的方式被克服。换句话说,是否可以编写一个完美 C++ 到 C 的编译器(以不支持的 C++ 特性为模)?
诀窍在于,您必须将宏扩展到足以进行可靠解析的程度,然后将它们折叠回未扩展的形式(因此它们再次可移植且独立于平台)。但是否存在根本不可能做到这一点的情况?
任何人都很难断然地说“是的,这是可能的”,但我很想看到任何具体的反例:由于某种深层原因无法以这种方式编译的代码 sn-ps。我对 C++ 和 C99 的反例都感兴趣。
我将从一个粗略的例子开始,只是为了说明我认为反例可能是什么样子。
#ifdef __SSE__
#define OP <
#else
#define OP >
#endif
class Foo {
public:
bool operator <(const Foo& other) { return true; }
bool operator >(const Foo& other) { return false; }
};
bool f() { return Foo() OP Foo(); }
这很棘手,因为OP 的值以及此处生成的方法调用是特定于平台的。但是编译器似乎有可能识别出语句的解析树依赖于宏的值,并将宏的可能性扩展为:
bool f() {
#if __SSE__
return Foo_operator_lessthan(...);
#else
return Foo_operator_greaterthan(...);
#endif
}
【问题讨论】:
-
有可能,但不会很漂亮。特别是 C99 具有 VLA,在 C90 中实现它们的唯一方法是使用
malloc、free,并为每个函数添加额外的不可见jmp_buf类型参数以处理代码执行 @987654328 的情况@ out of functions 包含 VLA。
标签: c++ c compiler-construction c-preprocessor