c++ - Lambda:是从 lambda 未定义行为中的函数范围捕获 const char *

标签 c++ lambda const-char

<分区>

我有一个 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 * 的情况很好奇。

最佳答案

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

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

Evaluating a string-literal results in a string literal object with static storage duration, initialized from the given characters as specified above. Whether all string literals are distinct (that is, are stored in nonoverlapping objects) and whether successive evaluations of a string-literal yield the same or a different object is unspecified.

(重点是我的)

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

关于c++ - Lambda:是从 lambda 未定义行为中的函数范围捕获 const char *,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58982891/

相关文章:

c - strtol、strtod 不安全吗?

c++ - GetLogicalDriveStrings() 和 char - 我哪里做错了

c++ - 运行时访问图书管理员类?

c++ - 模拟基数/底数为 36 的 ulltoa()

c++ - 调用 ADL 时,表达式和 namespace 之间是否会发生冲突?

Java 8 Stream API 相当于嵌套 for 循环

c++ - 给定一个包含 lambda 函数的调用堆栈,如何确定其来源?

C++ Builder 和 Excel Automation,从哪里开始?

python - 如何用多行编写 python lambda?