This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/63717] New: Value-initialization performs defaut-initialization when =default is outside the class declaration


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63717

            Bug ID: 63717
           Summary: Value-initialization performs defaut-initialization
                    when =default is outside the class declaration
           Product: gcc
           Version: 4.9.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: morwenn29 at hotmail dot fr

I have this minimal test case:

    struct foo
    {
        unsigned value;

        foo();
        foo(unsigned value):
            value(value)
        {}
    };

    foo::foo()
        = default;

    int main()
    {
        foo bar{};
    }

In this test case, foo bar{}; should zero-initialize bar and thus
zero-initialize value (see http://stackoverflow.com/q/26699720/1364752 for a
discussion about that). However, value is sometimes initialized with garbage
instead of being initialized with 0. Here is the assembly produced by the
example above:

    push   %ebp
    mov    %esp,%ebp
    and    $0xfffffff0,%esp
    sub    $0x10,%esp
    call   0x402060 <__main>
    lea    0xc(%esp),%eax
    mov    %eax,%ecx
    call   0x401610 <foo::foo()>
    mov    $0x0,%eax
    leave
    ret

As you can see, the default constructor of foo is called, but value is not
zero-initialized here. However, if we move = default in the class declaration:

    struct foo
    {
        unsigned value;

        foo() = default;
        foo(unsigned value):
            value(value)
        {}
    };

    foo::foo()
        = default;

    int main()
    {
        foo bar{};
    }

Then, the produced assembly is not the same anymore and value is properly
zero-initialized as expected:

    push   %ebp
    mov    %esp,%ebp
    and    $0xfffffff0,%esp
    sub    $0x10,%esp
    call   0x402050 <__main>
    movl   $0x0,0xc(%esp) ; init value (?)
    mov    $0x0,%eax
    leave
    ret

I am not really good at reading assembly but I fixed my problem by moving the
=default into the class instead separating the declaration of the default
constructor and its definition. If I correctly read both the standard and the
assembly, I am pretty sure that this is a GCC bug.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]