我想生成一些C,并验证它是否能编译,所以我想使用C的一个子集来使验证更容易.然而我不想限制可以写的东西,所以我想要一个C的子集,这样给定任何C程序,你可以写一个程序,在现代编译器中编译成相同的机器代码。
例如,我认为以下结构是不必要的。
x++
, ++x
, x—-
, —-x
+=
, -=
, *=
, /=
, %=
, <<=
, >>=
, &=
, ^=
, |=
a[i]
p->m
还有其他的吗,我的任何一个都是某些优化所必需的吗?
你可以从 "C的子集 "中排除的东西,而不要求编译器的输出有什么不同,包括。
前增量和后增量 (x++
, ++x
). 这包括必须明确模拟副作用的特殊情况。
赋值运算符(x =+ ..
等)。) 这包括那些必须明确模拟副作用的特殊情况。
无论是数组访问(但不是数组定义)还是 *
作为指针解除引用(例如 x = *pointer;
取代为 x = pointer[0];
).
几乎所有的空白(例如,除了换行符以外的所有内容),包括注释和续行 (\
在行末)
卦象
do
, while
和 for
(均可更换为 if
和 goto
);但不是 switch
(我希望现代编译器使用的是 switch
关键字作为 "考虑转换为跳表 "的提示)
break;
(可以用 goto
)
的 inline
关键字
表达式中的括号。这些括号可以通过重新排列表达式或使用临时变量来消除(例如,用 x = (y + z) * 3;
替换为 temp = y + z; x = temp * 3;
).
半数的关系运算符(如。x = a != b
可以被替换为 x = !(a == b);
, x = a <= b
可替换为 x = !(a > b);
等)。)
十六进制和八进制为数值常数(可以用十进制常数代替)
否定。可以用减法代替(如 x = -y;
代之以 x = 0 - y;
)
要么 &
或 |
. 用使用德摩根定律的等价物代替(例如:)。x = a & b;
代之以 x = ~(~a | ~b);
).
要么 &&
或 ||
. 用使用德摩根定律的等价物代替(例如:)。if( (a == b) && (c == d) )
代之以 if( !(a != b) || (c != d) )
).
用逗号作为语句分隔符。使用逗号作为语句分隔符的代码总是可以被重构成不使用逗号的代码(例如. for(i = 0, j = 0; i < k; i++, j++) { foo(); }
替换为 j = 0; for(i = 0; i < k; i++) { foo(); j++; }
或者 i = 0; j = 0; if(i < k) goto done; next: ; foo(); i = i + 1; j = j + 1; if( !(i < k)) goto next; done: ; }
.
enum
. 可由一组 #define ..
.
注1:"不要求编译器的输出有差异"(在我的第一句话中)的意思是,编译器的输出可能有差异,但不要求。
注2:我 "非常不喜欢 "阅读做这些事情的源代码。为了源代码的可读性(例如调试你的 "Idris转C "转换器的输出,看看你的转换器是否有bug),我会避免做这个列表中的任何事情。