初始化std :: array< char,x>成员在构造函数中使用字符串文字。 GCC bug? [英] Initializing std::array<char,x> member in constructor using string literal. GCC bug?

查看:185
本文介绍了初始化std :: array< char,x>成员在构造函数中使用字符串文字。 GCC bug?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的示例使用字符串文字在构造函数中初始化 std :: array< char,N> 成员不会在GCC 4.8上编译,而是使用Clang 3.4。

  #include< iostream> 
#include< array>

struct A {
std :: array< char,4> X;
A(std :: array< char,4> arr):x(arr){}
};


int main(){
//与Clang 3.4一起工作,在GCC 4.8中有错误。
//它应该等于A a({'b','u','g','\0'});
A a({bug}); (std :: size_t i = 0; i< a.x.size(); ++ i)
std :: cout<< a.x [i]<< \\\
;

返回0;
}

第一印象看起来像是GCC bug。我觉得它应该编译,因为我们可以直接用字符串文字初始化 std :: array< char,N> 。例如:

  std :: array< char,4> test = {bug}; //作品

我很想知道标准对此有何评论。

解决方案

是的,您的代码是有效的;这是一个gcc中的错误。



这是一个更简单的程序,用于演示错误(我已经替换了 std :: array< char,4> 与 S 并且摆脱了 A ,因为我们可以在函数中演示错误返回(这使分析更简单,因为我们不必担心构造函数重载):

pre $ struct $ {char c [4];};
S f(){return {xxx};}

这里我们有一个类型为 S 的目标对象,它是从 braced-init-list copy-initialized (8.5p15) {xxx} ,所以对象是列表初始化(8.5p17b1)。 S 是一个聚合(8.5.1p1),因此执行聚合初始化(8.5.4p3b1)。在聚合初始化中,成员 c copy初始化从相应的初始化子句 xxx(8.5.1p2)现在我们返回到8.5p17,类型 char [4] 并初始化字符串文字xxx,所以8.5p17b3指向8.5.2, code> char 数组由字符串的连续字符(8.5.2p1)初始化。



请注意,gcc很好复制初始化 S s = {xxx}; ,同时打破各种形式的复制和直接初始化;参数传递(包括构造函数),函数返回,以及基础和成员初始化:

pre $ struct $ {char c [4 ]。 };
S f(){return {xxx}; }
void g(S){g({xxx}); }
auto p = new S({xxx});
struct T {S s; T():s({xxx}){}};
struct U:S {U():S({xxx}){}};
S s({xxx});

最后一个特别有趣,因为它可能与 bug 43453


The following example initializing a std::array <char, N> member in a constructor using a string literal doesn't compile on GCC 4.8 but compiles using Clang 3.4.

#include <iostream>
#include <array>

struct A {
  std::array<char, 4> x; 
  A(std::array<char, 4> arr) : x(arr) {}
};


int main() {
    // works with Clang 3.4, error in GCC 4.8.
    // It should be the equivalent of "A a ({'b','u','g','\0'});"
    A a ({"bug"});
    for (std::size_t i = 0; i < a.x.size(); ++i)
        std::cout << a.x[i] << '\n';

    return 0;
}

On first impression it looks like a GCC bug. I feel it should compile as we can initialize a std::array<char, N> directly with a string literal. For example:

std::array<char, 4> test = {"bug"}; //works

I would be interested to see what the Standard says about this.

解决方案

Yes, your code is valid; this is a bug in gcc.

Here's a simpler program that demonstrates the bug (I've replaced std::array<char, 4> with S and got rid of A, as we can demonstrate the bug just in function return (this makes the analysis simpler, as we don't have to worry about constructor overloading):

struct S { char c[4]; };
S f() { return {"xxx"}; }

Here we have a destination object of type S that is copy-initialized (8.5p15) from the braced-init-list {"xxx"}, so the object is list-initialized (8.5p17b1). S is an aggregate (8.5.1p1) so aggregate initialization is performed (8.5.4p3b1). In aggregate initialization, the member c is copy-initialized from the corresponding initializer-clause "xxx" (8.5.1p2). We now return to 8.5p17 with destination object of type char[4] and initializer the string literal "xxx", so 8.5p17b3 refers us to 8.5.2 and the elements of the char array are initialized by the successive characters of the string (8.5.2p1).

Note that gcc is fine with the copy-initialization S s = {"xxx"}; while breaking on various forms of copy- and direct-initialization; argument passing (including to constructors), function return, and base- and member-initialization:

struct S { char c[4]; };
S f() { return {"xxx"}; }
void g(S) { g({"xxx"}); }
auto p = new S({"xxx"});
struct T { S s; T(): s({"xxx"}) {} };
struct U: S { U(): S({"xxx"}) {} };
S s({"xxx"});

The last is particularly interesting as it indicates that this may be related to bug 43453.

这篇关于初始化std :: array&lt; char,x&gt;成员在构造函数中使用字符串文字。 GCC bug?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆