【问题标题】:Odd syntax in C++: return { .name=value, ... }C++ 中的奇怪语法:return { .name=value, ... }
【发布时间】:2015-10-14 03:39:57
【问题描述】:

在阅读一篇文章时,我遇到了以下功能:

SolidColor::SolidColor(unsigned width, Pixel color)
  : _width(width),
    _color(color) {}

__attribute__((section(".ramcode")))
Rasterizer::RasterInfo SolidColor::rasterize(unsigned, Pixel *target) {
  *target = _color;
  return {
    .offset = 0,
    .length = 1,
    .stretch_cycles = (_width - 1) * 4,
    .repeat_lines = 1000,
  };
}

作者对return语句做了什么?我以前没见过这样的东西,我不知道如何搜索它......它对普通 C 也有效吗?

编辑: link to the original article

【问题讨论】:

  • 在 C 中有效,C++ 某些编译器的非标准扩展(从 C++11 开始,此功能不在 C++ 标准中。)
  • 参见the C standard,第 6.5.2.5 复合文字部分,第 10 点(关于指定的初始值设定项)。
  • 我很确定这对纯 C 有效,而 not 对 C++ 有效。
  • @ShafikYaghmour:可能有很多重复项,但被提名的并不是(甚至接近于)重复项——它是在问 为什么 C++ 没有指定的初始化器(答案几乎仅限于为什么的问题)。这是在询问语法 means 的含义,而不是为什么它在 C++ 中不存在。您找到的那个至少相当接近重复(但至少在 IMO,当作为重复关闭时,重要的是不要仅仅关闭,而是要确保指定重复的答案确实回答了所提出的问题在这里)。
  • @Michael:复合文字 需要在{ 之前加上括号类型。并且指定的初始值设定项不是标准的 C++(但是 - afaik - gcc 也允许它们作为 C++ 的扩展)。

标签: c++ return


【解决方案1】:

这不是有效的 C++。

它(某种程度上)使用了 C 中的几个特性,称为“复合文字”和“指定初始化程序”,一些 C++ 编译器支持作为扩展。 “某种”来自这样一个事实,即作为一个合法的 C 复合文字,它应该具有看起来像强制转换的语法,所以你会有类似的东西:

return (RasterInfo) {
    .offset = 0,
    .length = 1,
    .stretch_cycles = (_width - 1) * 4,
    .repeat_lines = 1000,
  };

然而,不管语法上的不同,它基本上是创建一个临时结构,其中的成员按照块中的指定初始化,所以这大致相当于:

// A possible definition of RasterInfo 
// (but the real one might have more members or different order).
struct RasterInfo {
    int offset;
    int length;
    int stretch_cycles;
    int repeat_lines;
};

RasterInfo rasterize(unsigned, Pixel *target) { 
    *target = color;
    RasterInfo r { 0, 1, (_width-1)*4, 1000};
    return r;
}

最大的区别(如您所见)是指定初始化器允许您使用成员名称来指定初始化器用于哪个成员,而不是仅取决于顺序/位置。

【讨论】:

  • 在 C++11 中只需 return { 0, 1, (_width-1)*4, 1000}; 即可,不需要 r。这使得 C++ 语法更接近于 C99 语法,并使两者的融合成为上面使用的语法。
【解决方案2】:

这是一个 C99 compound literal。此功能是 C99 特有的,但 gcc 和 clang 也选择在 C++ 中实现它(如extension)。

6.26 复合字面量

ISO C99 支持复合文字。复合文字看起来像 包含初始化程序的强制转换。它的值是类型的对象 在强制转换中指定,包含在 初始化器;它是一个左值。作为扩展,GCC 支持复合 C90 模式和 C++ 中的文字,尽管语义有点 在 C++ 中有所不同。

【讨论】:

  • 嗯,什么? “......看起来像一个包含初始化程序的演员表。”这如何符合这个问题? -1.
  • 那是不是复合初始化器_!这将需要在块之前有一个带括号的类型。并且原始代码是 C++,即使没有指定的初始化程序。
  • 这个答案不正确。它类似于 C99 复合文字,但绝对不是。
猜你喜欢
  • 1970-01-01
  • 2013-12-12
  • 2015-01-12
  • 2017-12-06
  • 1970-01-01
  • 2016-08-26
  • 1970-01-01
  • 2015-08-05
相关资源
最近更新 更多