Это большой вопрос, поэтому позвольте мне кое-что из этого сделать:
- Давайте проигнорируем тот факт, что некоторые функции C ++ не могут быть реализованы в C (например, поддержкаосновная инициализация для любого глобального статического объекта, который связан с).
- Это мысленный эксперимент о том, что теоретически возможно.Пожалуйста, не пишите, чтобы сказать, насколько сложно это будет (я знаю), или что я должен вместо этого делать X.Это не практический вопрос, это забавный теоретический вопрос.:)
Вопрос заключается в следующем: возможно ли теоретически скомпилировать C ++ или C99 в C89, который такой же переносимый , что и исходный код?
Cfront иComeau C / C ++ уже компилировать C ++ в C.Но для Comeau C, который они производят, не является портативным, по словам торгового персонала Comeau.Я сам не использовал компилятор Comeau, но я предполагаю, что причины этого:
- Макросы, такие как INT_MAX, offsetof () и т. Д., Уже расширены, и их расширение является платформенным.конкретный.
- Условная компиляция, такая как
#ifdef
, уже решена.
Мой вопрос заключается в том, можно ли решить эти проблемы надежным способом.Другими словами, может ли быть написан совершенный C ++ to C компилятор (по модулю неподдерживаемых возможностей C ++)?
Хитрость заключается в том, что вам нужно расширять макросы настолько, чтобы выполнять надежный анализ, нозатем сложите их обратно в их нерасширенные формы (чтобы они снова были портативными и независимыми от платформы).Но есть ли случаи, когда это принципиально невозможно?
Было бы очень сложно категорически сказать «да, это возможно», но мне очень интересно увидеть какие-то конкретные контрпримеры: фрагменты кода, которые не могутбыть составлен таким образом по какой-то глубокой причине.Мне интересны контрпримеры 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
}