在 C 语言中编译时评估的预处理器函数
我想编写在以下位置评估的预处理器函数/数组 编译时间。例如,如果我定义
#define MYARR[] {5,4,3,2,1,0}
then,则应将代码
int x = R[0];
呈现给
int x = 5;
编译器。 (当然索引中只能使用文字)。 如果代码大小/内存很关键并且我们不想这样做,那么这一点很重要 存储 MYARR
,但我们需要它来方便编码。
编译时函数也很好。例如,类似
#define MYMAP(n)
#if n==1
5
#else
2
So, 语句
int x = MYMAP(4);
应该呈现给编译器,因为
int x = 2;
显然,我们必须使用文字作为参数。这可能吗?
I want to write preprocessor functions/arrays that are evaluated at
compile time. For example, if I define
#define MYARR[] {5,4,3,2,1,0}
then, the code
int x = R[0];
should be presented as
int x = 5;
to the compiler. (Of course only literals can be used in the index).
This is important if code size/memory is critical and we don't want to
store MYARR
, but we need it for coding convenience.
Compile time functions would also be good. For example, something like
#define MYMAP(n)
#if n==1
5
#else
2
So, the statement
int x = MYMAP(4);
should be presented to the compiler as
int x = 2;
Obviously, we have to use a literal as the argument. Is this possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
当然有可能。虽然您可以手动执行此操作,但 Boost.Preprocessor 已经为您提供了所需的工具:
... 转换为:
它还包括算术、比较和控制结构,例如
IF
、FOR
、FOR_EACH< /code>、枚举……您只需记住,您可以使用的数据类型相当有限。
再次使用Boost.PP,你的第二个例子可以像这样完成:
你当然可以手动实现Boost.PP所做的事情,但考虑到这需要时间和精力,我个人不会打扰。
作为 C 用户,您不会对 Boost 的其余部分感兴趣,因此您可能需要使用 bcp 提取预处理器组件。
Sure it’s possible. While you could do that manually, Boost.Preprocessor already gives you the tools you need:
... gets transformed to:
It also includes arithmetic, comparisons and control structures like
IF
,FOR
,FOR_EACH
, enumerations, ... You just have to keep in mind that the data types you can work with are rather limited.Utilizing Boost.PP again, your second example can be done like so:
You can of course implement manually what Boost.PP does, but considering the time and effort needed for this I personally wouldn't bother.
As a C user, you won't be interested in the rest of Boost, so you might want to use bcp to extract the preprocessor components.
标准 C 预处理器不会执行您想要的操作。为了可靠地获得这种行为,您将需要一个更强大的非标准预处理工具。然而,我对可用的内容还不够熟悉,无法引导您找到您可能想要的内容。
尽管如此,在第二种情况下,您仍然可以在大多数现代编译器上获得您想要的效果。例如:
仍将呈现给编译器为:
但是编译器本身,如果它是一个合理的现代编译器并且您允许它优化,可能会注意到这个表达式可以在编译时计算 -时间并会发出与然而相同的代码
,保证编译器将执行此优化。
The standard C preprocessor will not do what you want. To get this sort of behavior reliably you are going to need a more powerful, nonstandard preprocessing tool. However, I'm not familiar enough with what's available to direct you to which one you might want.
Although, in the second case, you may still be able to get the effect you want on most modern compilers. For example:
will still be presented to the compiler as:
but the compiler itself, if it is a reasonable modern compiler and you allow it to optimize, will likely notice that this expression can be evaluated at compile-time and will emit code that is identical to
However, there's nothing that guarantees that a compiler will perform this optimization.
在 C99 中(你确实需要它;C89 不行)你可以这样做,
只要你的类型是
int
,但任何其他类型都会做。奇怪的东西(int const[]){ 3, 4, 5, 6, 7}
被称为复合文字。基本类型的 const 告诉编译器它不会被修改,并且他可以将所有具有相同内容的实例别名到相同的固定位置。一般来说,对于这种方法,大多数编译器将能够完全优化对数组的任何引用,只要
N
是一个可以在编译时计算的表达式,例如固定值7
或'a'
左右。如果不是这种情况,编译器必须在某处创建数组对象。使用
const
,他可以只生成它的一份副本,无论您在代码中调用宏的频率如何。当他设法这样做时,数组的初始化将在编译时完成,因此不会有编译时开销。我检查了我机器上的三个编译器:
gcc
和clang
分配数组堆栈和每个单独的这个
调用
MyMap
,坏,因为开销与数组的大小成正比。opencc
静态分配数组但为每次调用创建一个新副本
到
MyMap
,更好,但还不够理想。In C99 (you really need that; C89 wouldn't do) you can do with something like
provided your type is
int
, but any other type would do. The weird thing(int const[]){ 3, 4, 5, 6, 7}
is called a compound literal. Theconst
in there for the base type tells the compiler that it will not be modified and that he may alias all occurrences with the same contents to the same fixed location.Generally, for this approach, most compilers will be able to completely optimize any reference to the array away, provided
N
is an expression that can be evaluated at compile time, such as a fixed value7
or'a'
or so.If this is not the case, the compiler has to create the array object somewhere. With the
const
he could be allowed to generate just one copy of it, regardless how often you call the macro in your code. When he manages to do so, the initialization of the array would be done at compile time, so there would be no compile time overhead.I checked this for the three compilers that I have on my machine:
gcc
andclang
allocate the array onthe stack and this for every single
call to
MyMap
, bad, since the overhead is proportional to the size of the array.opencc
allocates the array staticallybut creates a new copy for every call
to
MyMap
, better, but not yet ideal.没有标准的预处理器命令可以按照您想要的方式处理数组。我建议你使用const。
那么对于 MYMAP 问题...
There is no standard preprocessor commands that handle arrays the way you are wanting. I suggest that you use a const.
Then for the MYMAP question...
myarr 对于字符我仍然可以
思考整数。我的地图是
myarr for chars I can do
still pondering ints. Mymap is