【发布时间】:2018-01-08 14:53:38
【问题描述】:
简单地说,有没有一种 ANSI-C 方法可以使函数成为常量表达式?
- 可以接受纯 ANSI-C 但 GNU 扩展 - 但不能使用 C++。
- 最好不依赖宏。
- 某些行为肯定类似于 C++
constexpr,并且不会在运行时解决。
背景:
我需要在没有浮点的嵌入式处理器中实现大量数学运算,因此我在我的应用程序中使用定点。
不过,我不喜欢在我的头文件中看到神秘的常量。
我的硬件需要几个浮点常量(例如130.7 microseconds、0.2503 mJ),并且我真的希望能够读取(和更改)我的常量,因为零件数据表值已列出。
在给定的时刻,我的硬件需要使用这个常量,例如,填写计时器重载值,并且由于这些值是常量,我希望有类似的东西:
// Header file.
static const int values_table[] =
{
_Time( 123.45 ), // 123.45 microseconds.
// ...
};
然后:
// Application source file.
int conv_to_timer( x ) { /* my calculations - all const. */ }
// ...
void my_code( void )
{
// ...
timer_reload = conv_to_timer( values_table[ index ] );
一种方法是让我的_Time( x ) 宏执行计时器值所需的所有计算,但它不灵活(即无法与外部的某些东西相比),也不便携(不同的硬件需要不同的计算)。
请给我一些优雅的方法的建议?
【问题讨论】:
-
我不太赞同您对使用宏的反对意见。特别是,是什么阻止了宏的扩展与“外部事物”进行比较?你是说它没有联系的事实吗?如果不同的硬件需要不同的计算,那么函数如何比宏更好?
-
没有。
constexpr是 C++ 中的一个额外功能,而不是(标准)C 中的 - 没有类似的东西。 -
感谢您的评论@JohnBollinger。宏的要点是它必须与我声明常量的位置相同,而函数可以位于不同的翻译单元中,因此不会因应用程序特定目的而污染头文件。我解释了吗?
-
而不是
_Time( 123.45 ), // 123.45 microseconds.,考虑一个宏ns_TO_RELOAD(123450),并删除FP,当代码应该不言自明时删除cmets。 -
@j4x 放弃 FP 的一个价值是宏数学在宏转换时不能很好地工作,如果有的话。此外,通过使用整数数学,可以精确控制到
reload单位的转换,而无需四舍五入和其他 FP 问题。喜欢#define ns_TO_RELOAD(ns) (((ns) + TICKS_PER_ns/2)/TICKS_PER_ns - 1)