0

我有一个 lambda,它使用在函数范围内定义的 const char *。lambda 在函数返回后执行。

void function() {
  const char * UNLOCK_RESULT = "unlockResult";
  .. 
  ..
 TestStep::verifyDictionary(test, [UNLOCK_RESULT](TestStep::Dictionary& dict){
    return 1 == dict[UNLOCK_RESULT].toInt();
  });
  ...
}

如果我查看 GCC 生成的程序集,保存“unlockResult”的实际字符数组是静态分配的。但我想知道这是否由标准保证,因为理论上 const char * 是函数范围。是捕获 const char * 未定义的行为,还是标准允许这样做,因为 C++ 处理 const char * 字符串时出现一些异常。

我知道我可以改变:

             const char * UNLOCK_RESULT="" 
to 
   constexpr const char * UNLOCK_RESULT=""

然后讨论就消失了,因为我什至不需要捕捉它,但我对 const char * 的情况很好奇。

4

2 回答 2

2

行为是明确定义的。

lambda[UNLOCK_RESULT](TestStep::Dictionary& dict){...}按值捕获指针。所以UNLOCK_RESULT在 lambda 内部是原始的副本UNLOCK_RESULT,后者在 lambda 的持续时间内不必存在。

现在字符串文字"unlockResult"具有静态存储持续时间,这意味着它在程序启动时分配并在程序持续时间内保持可用:

所有没有动态存储持续时间、没有线程存储持续时间和非本地变量的变量都有静态存储持续时间。这些实体的存储将持续到程序的持续时间。

于 2019-11-21T20:28:55.190 回答
2

您正在混合 2 个概念。在函数范围内是变量UNLOCK_RESULT本身,所以如果你尝试使用引用或指向变量的指针,那么你会得到 UB。但是当您使用指向静态数据的变量的值时,您完全可以,因为这样的指针在函数终止后不会失效。

如果您的问题是在函数终止后指向字符串文字的指针是否有效,那么它是有效的,并且由 C++ 标准保证具有静态持续时间:

评估字符串文字会产生一个具有 静态存储持续时间的字符串文字对象,从上面指定的给定字符初始化。是否所有字符串文字都是不同的(即,存储在不重叠的对象中)以及字符串文字的连续评估是否产生相同或不同的对象是未指定的。

(重点是我的)

顺便说一句,将标识符用于所有大写的常量是一个老习惯,因为它们过去是在预处理器中定义的。当你有常量大写的编译时标识符时,你会遇到这个习惯试图最小化的完全相同的问题。

于 2019-11-21T20:10:14.283 回答