当前位置: 首页 > 知识库问答 >
问题:

局部常量变量不可计算,但无法找出原因

司马自明
2023-03-14

我尝试将int作为参数并单独对其字节进行操作,例如取0xDEADF00D并逐个处理每个字节:0xDE 0xAD 0xF0 0x0D

为此,我执行了以下代码

template <int state, int seed>
constexpr static uint32_t CalculateRandomFromState()
{
    const char bytes[4] = {
        (state >> 24) & 0xFF,
        (state >> 16) & 0xFF,
        (state >> 8) & 0xFF,
         state & 0xFF,
    };

    constexpr auto value = Compiletime::Hash<seed, sizeof(bytes)>(bytes);

    return value;
}

HashFn的sig为:

template <const uint32_t seed, const uint32_t size = NULL>
constexpr uint32_t Hash(const char* message)

编译失败,并显示:

错误C2131:表达式未计算为常量

注意:失败是由于在变量的生命周期之外读取了变量导致的

注意:请参阅“字节”的用法

我在StackOverflow上读过一些关于参数在编译时可能无法求值的主题(这就是为什么我将大多数参数切换为模板变量,所以100%保证它们是编译时的),但在这种情况下,它给出错误的原因似乎不符合逻辑。bytes值取决于编译时值,byte也是常量。

为什么会超出它的生命周期?如果我把“somestring”替换为变量bytes,那么它可以完美编译。这里什么不是恒定可评估的?

共有1个答案

谢运良
2023-03-14

函数声明上的 constexpr 不需要所有计算路径都指向常量表达式。函数调用的结果是否为 constexpr 取决于输入参数。

假设您的哈希函数如下所示:

template <uint32_t seed, uint32_t size>
constexpr uint32_t Hash(const char* message)
{
    uint32_t rc = seed;
    for (uint32_t i = 0; i < size; ++i)
        rc += message[i];
    return rc;
}

这将计算为一个常量表达式 iff 消息是一个常量表达式。

但您使用的是一个非常量表达式:

    const char bytes[4] = {
        (state >> 24) & 0xFF,
        (state >> 16) & 0xFF,
        (state >> 8) & 0xFF,
         state & 0xFF,
    };

    constexpr auto value = Compiletime::Hash<seed, sizeof(bytes)>(bytes);

每次调用<code>Hash(byte)</code>时,<code>byte</code<都可能具有不同的地址。

您可以通过简单地声明bytesconstexpr来实现:

template <int state, int seed>
constexpr static uint32_t CalculateRandomFromState()
{
    constexpr char bytes[4] = {
        (state >> 24) & 0xFF,
        (state >> 16) & 0xFF,
        (state >> 8) & 0xFF,
         state & 0xFF,
    };

    constexpr auto value = Compiletime::Hash<seed, sizeof(bytes)>(bytes);

    return value;
}
 类似资料:
  • 主要内容:局部变量,全局变量,局部变量和全局变量的综合示例在《 C语言形参和实参的区别》中提到,形参变量要等到函数被调用时才分配内存,调用结束后立即释放内存。这说明形参变量的作用域非常有限,只能在函数内部使用,离开该函数就无效了。 所谓 作用域( Scope ) ,就是变量的有效范围。 不仅对于形参变量,C语言中所有的变量都有自己的作用域。决定变量作用域的是变量的定义位置。 局部变量 定义在函数内部的变量称为 局部变量(Local Variable) ,

  • Lua 的设计有一点很奇怪,在一个 block 中的变量,如果之前没有定义过,那么认为它是一个全局变量,而不是这个 block 的局部变量。这一点和别的语言不同。容易造成不小心覆盖了全局同名变量的错误。 定义 Lua 中的局部变量要用 local 关键字来显式定义,不使用 local 显式定义的变量就是全局变量: g_var = 1 -- global var local l_va

  • 简介 在前面的章节中,我已经讲述了如何定义函数。在本节中,我讲介绍局部变量,这将会使定义函数变得更加容易。 let表达式 使用let表达式可以定义局部变量。格式如下: (let binds body) 变量在binds定义的形式中被声明并初始化。body由任意多个S-表达式构成。binds的格式如下: [binds] → ((p1 v1) (p2 v2) ...) 声明了变量p1、p2,并分别

  • 局部变量用于模版渲染,也就是模版中的 site 变量。 默认变量 变量 描述 posts 所有文章 pages 所有分页 categories 所有分类 tags 所有标签 获取变量 hexo.locals.get('posts') 设置变量 hexo.locals.set('posts', function(){ return ... }); 移除变量 hexo.locals.remove(

  • 问题内容: 我了解Python中局部变量和全局变量的概念,但是我只是有一个问题,为什么下面的代码中会出现错误?Python逐行执行代码,因此在读取第5行之前,它不知道a是局部变量。Python尝试执行第5行后,会回退一行并将其标记为错误吗? 问题答案: 设置和测试 为了分析您的问题,让我们创建两个独立的测试函数来复制您的问题: 版画。因此,调用此函数不是问题,而是在下一个函数上: 我们收到一个错误

  • defineequationquadratic: selectsolutionsungratic: