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++/51847] New: incorrect primitive array initialization in generic methods


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51847

             Bug #: 51847
           Summary: incorrect primitive array initialization in generic
                    methods
    Classification: Unclassified
           Product: gcc
           Version: 4.6.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: bruno-gcc@defraine.net


Created attachment 26315
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=26315
Test case

According to my understanding of the (C++11) standard, a new expression without
an initializer (5.3.4, clause 15) should default-initialize, which in the case
of an array means to default-initialize each of the elements, which in case of
doubles means no initialization (8.5, clause 6).

Hence, the expression "new double[n]" should not initialize the elements of the
allocated double array.

I observe that gcc correctly implements this behavior when the expression
appears in a standard method. However, when the expression appears in a generic
method, the array may (incorrectly) be initialized depending on some tricky
conditions regarding parameter "n".

I include a simple testcase, which checks whether "new double[n]" initializes
the elements depending on the context where this expression appears: (1) in a
standard method (2) in a generic method (3) in a generic method with a generic
method invocation as argument (4) in a generic method with a casted argument.

To detect whether the array is initialized, I rely on the fact that (at least
on my system) successive allocations/deallocations for the same size normally
return the same memory area. (This is not guaranteed; perhaps the testcase can
be made more deterministic with placement new. Alternatively, one can look at
the assembler output to check whether initialization code is generated or not.)

Actual output:
$ g++ -Wall -o init init.cpp
$ ./init
Filling 0x7fd8db000000
Testing 0x7fd8db000000: no-init
Filling 0x7fd8db000000
Testing 0x7fd8db000000: no-init
Filling 0x7fd8db000000
Testing 0x7fd8db000000: init
Filling 0x7fd8db000000
Testing 0x7fd8db000000: no-init
Filling 0x7fd8db000000
Testing 0x7fd8db000000: init

Expected output:
$ g++ -Wall -o init init.cpp
$ ./init
Filling 0x7fd8db000000
Testing 0x7fd8db000000: no-init
Filling 0x7fd8db000000
Testing 0x7fd8db000000: no-init
Filling 0x7fd8db000000
Testing 0x7fd8db000000: no-init
Filling 0x7fd8db000000
Testing 0x7fd8db000000: no-init
Filling 0x7fd8db000000
Testing 0x7fd8db000000: no-init

Whether the array is initialized or not had a very observable performance
impact in my actual application. I speculate this occurres because the array is
present in the caches after the initialization, which make subsequent
operations go faster.

This is the version of gcc that I'm using:

$ g++ -v
Using built-in specs.
COLLECT_GCC=g++-fsf-4.6
COLLECT_LTO_WRAPPER=/sw/lib/gcc4.6/libexec/gcc/x86_64-apple-darwin11.2.0/4.6.2/lto-wrapper
Target: x86_64-apple-darwin11.2.0
Configured with: ../gcc-4.6.2/configure --prefix=/sw --prefix=/sw/lib/gcc4.6
--mandir=/sw/share/man --infodir=/sw/lib/gcc4.6/info
--enable-languages=c,c++,fortran,lto,objc,obj-c++,java --with-gmp=/sw
--with-libiconv-prefix=/sw --with-ppl=/sw --with-cloog=/sw --with-mpc=/sw
--with-system-zlib --x-includes=/usr/X11R6/include --x-libraries=/usr/X11R6/lib
--program-suffix=-fsf-4.6 --enable-cloog-backend=isl
Thread model: posix
gcc version 4.6.2 (GCC)


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