简体   繁体   English

静态地初始化变量(在编译时)

[英]initialize a variable statically (at compile time)

1) I've got many constants in my C algo. 1)我的C算法中有很多常量。 2) my code works both in floating-point and fixed-point. 2)我的代码在浮点数和定点数中均有效。

Right now, these constants are initialized by a function, float2fixed, whereby in floating-point it does nothing, while in fixed-point, it finds their fixed-point representation. 现在,这些常量已由float2fixed函数初始化,从而在浮点中不执行任何操作,而在定点中则查找其定点表示形式。 For instance, 0.5f stays 0.5f if working in floating-point, whereas it uses the pow() routine and becomes 32768 if working in fixed-point and the fixed-point representation is Qx.16. 例如,如果在浮点工作,则0.5f保持为0.5f,而它使用pow()例程,而在定点工作且定点表示为Qx.16时,则变为32768。

That's easy to maintain, but it takes a lot of time actually to compute these constants in fixed-point (pow is a floatin-point function). 这很容易维护,但是在定点计算这些常量实际上需要花费很多时间(pow是浮点函数)。 In C++, I'd use some meta-programming, so the compiler computes these values at compile-time, so there's no hit at run-time. 在C ++中,我将使用一些元编程,因此编译器会在编译时计算这些值,因此在运行时不会造成任何影响。 But in C, thats not possible. 但是在C语言中,那是不可能的。 Or is it? 还是? Anybody knows of such a trick? 有人知道这样的把戏吗? Is any compiler clever enough to do that? 有没有足够的编译器可以做到这一点?

Looking forward to any answers. 期待任何答案。

A 一种

Rather than using (unsigned)(x*pow(2,16)) to do your fixed point conversion, write it as (unsigned)(0.5f * (1 << 16)) 而不是使用(unsigned)(x*pow(2,16))进行定点转换,而是将其写为(unsigned)(0.5f * (1 << 16))

This should be an acceptable as a compile-time constant expression since it involves only builtin operators. 作为编译时常量表达式,这应该是可以接受的,因为它仅涉及内置运算符。

When using fixed-point, can you write a program that takes your floating point values and converts them into correct, constant initializers for the fixed point type, so you effectively add a step to the compilation that generates the fixed point values. 使用定点时,是否可以编写一个程序来获取浮点值并将其转换为定点类型的正确的常量初始值设定项,因此可以有效地向编译中添加一个生成定点值的步骤。

One advantage of this will be that you can then define and declare your constants with const so that they won't change at run-time - whereas with the initialization functions, of course, the values have to be modifiable because they are calculated once. 这样的优点之一是,您可以使用const定义和声明常量,这样它们就不会在运行时更改-而使用初始化函数,当然,这些值必须可修改,因为它们只计算一次。


I mean write a simple program that can scan for formulaic lines that might read: 我的意思是写一个简单的程序来扫描可能会显示的公式行:

const double somename = 3.14159;

it would read that and generate: 它会读取并生成:

const fixedpoint_t somename = { ...whatever is needed... };

You design the operation to make it easy to manage for both notations - so maybe your converter always reads the file and sometimes rewrites it. 您设计该操作是为了使其易于管理这两种表示法-因此,转换器可能总是读取文件,有时还会重写文件。

datafile.c:   datafile.constants converter
        converter datafile.constants > datafile.c

Recent versions of GCC ( around 4.3 ) added the ability to use GMP and MPFR to do some compile-time optimisations by evaluating more complex functions that are constant. GCC的最新版本(大约4.3)增加了使用GMP和MPFR的能力,可以通过评估更复杂的常量函数来进行一些编译时优化。 That approach leaves your code simple and portable, and trust the compiler to do the heavy lifting. 这种方法使您的代码简单易行,并且信任编译器来完成繁重的工作。

Of course, there are limits to what it can do, and it would be hard to know if it's optimizing a given instance without going and looking at the assembly. 当然,它的功能是有限的,并且如果不去查看程序集就很难知道是否在优化给定的实例。 But it might be worth checking out. 但这可能值得一试。 Here's a link to the description in the changelog 这是更改日志中描述的链接

In plain C, there's not much you can do. 在普通C语言中,您无能为力。 You need to do the conversion at some point, and the compiler doesn't give you any access to call interesting user-provided functions at compile time. 您需要在某个时候进行转换,并且编译器不允许您在编译时调用有趣的用户提供的函数。 Theoretically, you could try to coax the preprocessor to do it for you, but that's the quick road to total insanity (ie you'd have to implement pow() in macros, which is pretty hideous). 从理论上讲,您可以尝试诱使预处理器为您完成此操作,但这是彻底疯狂的捷径(即,您必须在宏中实现pow(),这非常丑陋)。

Some options I can think of: 我能想到的一些选择:

  1. Maintain a persistent cache on disk. 在磁盘上维护持久性缓存。 At least then it'd only be slow once, though you still have to load it, make sure it's not corrupt, etc. 至少那时它只会变慢一次,尽管您仍然必须加载它,确保它没有损坏,等等。

  2. As mentioned in another comment, use template metaprogramming anyway and compile with a C++ compiler. 如另一条评论中所述,无论如何都要使用模板元编程,并使用C ++编译器进行编译。 Most C works just fine (arguably better) with a C++ compiler. 大多数C使用C ++编译器都能很好地工作(可以说更好)。

Hmm, I guess that's about all I can think of. 嗯,我想这就是我能想到的。 Good luck. 祝好运。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM