在C++20中,通常在析构函数中具有非constexpr行为的类的constexpr实例。

huangapple go评论141阅读模式
英文:

constexpr instances of class that usually have non-constexpr behavior in the destructor, in C++20

问题

I would like to be able to create constexpr values for a type that usually has a non-trivial destructor. Unfortunately, I'm using C++20, so don't have if consteval. Here is a minimal working example that is accepted by gcc 12.2.1 and clang++ 15.0.7, but I'm not sure if it's legal:

#include <type_traits>
#include <string.h>

struct secret {
  int value_;
  constexpr secret(int value) : value_(value) {}
  constexpr ~secret() {
    if (!std::is_constant_evaluated())
      explicit_bzero(&value_, sizeof(value_));
  }
};

constexpr secret my_secret = 5;
secret my_destroyed_secret = 6;

My questions are:

  1. Is it legal to call a function like explicit_bzero from within a constexpr destructor? Since the if in the destructor is not constexpr, it seems like it should be illegal.
  2. If it is legal, then why?
  3. If it is not legal, then is there any other way to accomplish what I want--basically clobber any destroyed value that wasn't constexpr constructed?
英文:

I would like to be able to create constexpr values for a type that usually has a non-trivial destructor. Unfortunately, I'm using C++20, so don't have if consteval. Here is a minimal working example that is accepted by gcc 12.2.1 and clang++ 15.0.7, but I'm not sure if it's legal:

#include &lt;type_traits&gt;
#include &lt;string.h&gt;

struct secret {
  int value_;
  constexpr secret(int value) : value_(value) {}
  constexpr ~secret() {
    if (!std::is_constant_evaluated())
      explicit_bzero(&amp;value_, sizeof(value_));
  }
};

constexpr secret my_secret = 5;
secret my_destroyed_secret = 6;

My questions are:

  1. Is it legal to call a function like explicit_bzero from within a constexpr destructor? Since the if in the destructor is not constexpr, it seems like it should be illegal.
  2. If it is legal, then why?
  3. If it is not legal, then is there any other way to accomplish why I want--basically clobber any destroyed value that wasn't constexpr constructed?

答案1

得分: 3

是的,它是合法的。在析构函数中的条件语句不是constexpr时,使用std::is_constant_evaluated是唯一正确的方式。

这是为了告诉您std::is_constant_evaluated()的评估(以及包含它的表达式)是否作为常量表达式(即在编译时评估的表达式)的一部分进行评估。如果您在if constexpr的条件中调用它,它将始终被评估为常量表达式,且只能是true,因为if constexpr的条件要求本身是常量表达式,无论整个if语句是否作为另一个常量表达式的一部分进行评估。

这似乎让人感到困惑的原因之一是,C++23引入了if consteval以替代std::is_constant_evaluated。请参阅提出C++23中的if consteval论文

英文:

> Is this code legal? Since the if in the destructor is not constexpr, it seems like it should be illegal.

> If it is legal, then why?

Yes, it is. Using std::is_constant_evaluated without constexpr in an if is the only correct way to use it.

It is supposed to tell you whether the evaluation of std::is_constant_evaluated() (and the expression containing it) is part of evaluation as a constant expression (i.e. compile-time evaluated expression) or not. If you call it inside a condition of a if constexpr then it is always evaluated as constant expression and can only ever be true, because the condition of if constexpr is required to be in itself a constant expression, regardless of whether or not the whole if statement is evaluated as part of another constant expression.

That this seems to confuse people is one of the reasons that if consteval was introduced in C++23 to replace std::is_constant_evaluated. See the paper which proposed if consteval for C++23.

huangapple
  • 本文由 发表于 2023年3月4日 04:09:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/75631478.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定