如何表示常量的类型

How to express the type for a constant?

本文关键字:常量 类型 表示 何表示      更新时间:2023-10-16

我必须在相对较少的行数中编写一些包含大量常量的函数

(不要担心我写公式的方式,它只是为了简单地表达我在一个小包中有很多常数的事实,这个具体的例子也很小,在实践中我每个函数至少有6-7个常数)

T foo( T x )
{
  return k1 * k2 * x - k3;
}

假设我对将常量声明为静态不感兴趣(在我的特定情况下,这也会导致命名约定的问题)const T k1 = 42;,我想找到一个替代方案。

一个可行的替代方案是

T foo( T x )
{
  return uint32_t{42} * uint32_t{21} * x - uint32_t{33};
}

现在主要有两个问题:

  • 我不确定这种声明是否会创建一个完整的对象或只是"一个数字"
  • 这是一个c++唯一的解决方案,我写了非常简单的函数,应该是C99+兼容。

为什么我想这样做?

这很简单,这个常量的值是高度可变的,非常小的值或大的值,非常小的值会浪费大量的空间,加上这个常量是数学常量,所以它们永远不会改变,我可以从第一个版本开始优化这一部分。

还有另一个方面,数字常量的默认类型是一个有符号整数,我想去一个任意大小的无符号整数类型。

函数外的静态声明const T k1 = 42;的问题是,不同的常数有相同的名称,常数的值不同,因为函数不同,但常数的名称,从数学上讲,是相同的,所以用这个解决方案,我最终会在同一作用域中对同一变量进行多个声明。这就是为什么我不能使用名称或这类声明。

你有什么想法可以用一种既兼容c++又兼容C的方式来写这个吗?

在C语言中,对于整数,您可以在数字上加上'U', 'L'或'LL',以几种组合方式使它们成为unsigned, longlong long

a = -1LL;  // long long
b = -1U;   // unsigned
c = -1ULL; // unsigned long long
d = -1LLU; // unsigned long long
e = -1LU;  // unsigned long
f = -1UL;  // unsigned long

在C中,另一种选择是强制转换。编译器很可能会做正确的事情:)

return (uint32)42 - (int64)10;

但是可能最好的选择,正如ouah在下面的评论中指出的那样,是对整数常量使用宏(C99 Standard 7.18.4)

a = UINT32_C(-1); // -1 of type uint_least32_t
b = INT64_C(42);  // 42 of type int_least64_t

这有什么问题吗?

inline T foo(T x)
{
    int k1 = 42;
    int k2 = 21;
    int k3 = 33;
    return 1ull * x * k1 * k2 - k3;
}

您对另一个答案的评论表明您不确定使用哪种类型的常量。我看不出用任何类型来表示这个常量有什么问题。

对于计算表达式,您需要考虑中间计算的大小和符号性。在这个例子中,我从1ull开始使用无符号算术模型2^64。如果你想用2^32进行算术建模,那就用1ul,以此类推。

你能详细说明你所说的"空间浪费"是什么意思吗?听起来好像您认为使用64位整型存在一些问题。你说的是什么样的"空间"?

另外,为了澄清,你不想声明k1全局的原因是因为k1在一个函数中具有不同的值,而不是在另一个函数中?(而不是有相同的值,但你认为它应该有不同的数据类型的原因)。