【问题标题】:Is it legal to call a destructor on int32_t?在 int32_t 上调用析构函数是否合法?
【发布时间】:2016-03-29 05:48:30
【问题描述】:

我刚刚发现以下代码不是有效的 C++(在 ~ 之后它不会在 int 处解析):

int x = 5;
x.~int();

但是,以下 sn-p 确实有效:

int32_t x = 5;
x.~int32_t();

这是因为 int32_t 在我的特定 C++ 实现中是 typedef,显然可以在任何类型定义的类型上调用析构函数。

我的问题是:是否需要任何 C++ 实现才能允许第二个片段进行编译?特别是,int32_t 是否保证为 typedef,如果编译器知道 typedef typedef 将某些内容转换为 int,是否需要允许销毁 typedef?

【问题讨论】:

  • 是的。 int32_t 不是内置类型,不允许是宏。
  • @Cheersandhth.-Alf C++14 标准草案将typedef signed integer type int32_t; 定义为int32_t 的定义。据我所知,这并没有为用户定义的类型和所有甚至宏留下太多空间。
  • 为了避免关闭问题/未解决问题之战,我不会投票关闭作为重复项,但是......这是链接问题的重复项。仅仅因为其他问题没有提到int32_t 并不意味着其他问题没有回答您的问题。
  • @DavidHammen,我现在失去了链接,但那里的答案解释了为什么它适用于模板参数。这并不意味着同样适用于 typedef,或者 int32_t 必须以 typedef 开头。所以从技术上讲,它没有回答我的任何具体问题。

标签: c++ destructor


【解决方案1】:

有一个明确的要求,int32_t 是一个 typedef。我们从 [cstdint.syn]/2 开始:

头文件定义了与 C 标准中的 7.18 相同的所有函数、类型和宏。

所以从那里我们看一下 C 库的需求:

typedef 名称 intN_t 指定宽度为 N、无填充位和二进制补码表示的有符号整数类型。

[强调添加]

所以是的,int32_t 必须是“typedef 名称”。

虽然(据我所知)它从未在规范文本中直接说明,但以下注释清楚地表明,为解析为内置类型的 typedef 调用析构函数旨在编译并成功( [class. dtor]/16):

注意:显式调用析构函数的符号可用于任何标量类型名称(5.2.4)。允许这样做可以编写代码,而不必知道给定类型是否存在析构函数。例如,

typedef int I;
I* p;
p->I::~I();

【讨论】:

  • sn-p 当然是未定义的行为(通过野指针访问成员)。或者标准是否保证在原语上使用这种语法是无操作的,并且成员访问实际上永远不会发生?
  • @BenVoigt:问得好。我不认为指针实际上应该被取消引用,但我不确定我能找到一个声明来肯定地说。
  • "唯一的影响是对点或箭头之前的后缀表达式求值。" (5.2.4) 那么(*p).I::~I() 不好但p->I::~I() 好?类型是什么实际上并不重要?看起来像个缺陷。
  • 我能想到的唯一显式调用析构函数的用例是销毁由placement new构造的东西,因为销毁和释放需要分开进行。由于 POD 除了释放内存之外并没有真正做任何销毁操作,因此在 POD 上显式调用析构函数应该是 NOP。
  • @user3528438:这不是唯一的用例。另一个是在联合的元素之间切换(现在你可以在联合中拥有非平凡的类型)。
猜你喜欢
  • 1970-01-01
  • 2014-10-23
  • 2013-06-25
  • 1970-01-01
  • 1970-01-01
  • 2014-10-25
  • 1970-01-01
  • 2016-01-23
  • 2012-03-18
相关资源
最近更新 更多