Bug 44577 - static local variables in class template methods are not optimized-away if not used
Summary: static local variables in class template methods are not optimized-away if no...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.4.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks:
 
Reported: 2010-06-18 10:05 UTC by Michael Schulze
Modified: 2015-12-28 00:21 UTC (History)
0 users

See Also:
Host: i586-redhat-linux
Target: i586-redhat-linux
Build: i586-redhat-linux
Known to work:
Known to fail: 4.4.1, 4.4.3
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Schulze 2010-06-18 10:05:24 UTC
IMO, in the following test program the variable s within the class template may be optimized-away in every case. Although, the variable is used as an argument for a function call, it is omit-able due to the definition of function t1 as "static inline" with its empty body. If I use instead of a class template a function template, this contained static local variable will be optimized-away, as expected.

[mschulze@teeth tst]$ cat test.cc
static inline void t1(const char* s) {}

template <typename T>
struct class_template {
    class_template() {
        static const char s[]="class_template";
        t1(s);
    }
};

template <typename T>
static inline void function_template() {
        static const char s[]="function_template";
        t1(s);
    }

int main(int, char**) {
    class_template<int> t;
    function_template<int>();
    return 0;
}

I compiled the program with

[mschulze@teeth tst]$ g++ -v
Using built-in specs.
Target: i586-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch=i586 --build=i586-redhat-linux
Thread model: posix
gcc version 4.4.1 20090725 (Red Hat 4.4.1-2) (GCC)

and then I used the string program to list the contained strings.

[mschulze@teeth tst]$ strings t
/lib/ld-linux.so.2
libstdc++.so.6
__gmon_start__
_Jv_RegisterClasses
__gxx_personality_v0
libm.so.6
libgcc_s.so.1
libc.so.6
_IO_stdin_used
__libc_start_main
CXXABI_1.3
GLIBC_2.0
PTRhP
QVhD
[^_]
class_template
[mschulze@teeth tst]$

The class_template string is present, but the function_template string not. If I omit the static keyword, it will disappear, too.



Thanks in advance,
Michael
Comment 1 Michael Schulze 2010-06-18 10:11:46 UTC
(In reply to comment #0)
> IMO, in the following test program the variable s within the class template may
> be optimized-away in every case. Although, the variable is used as an argument
> for a function call, it is omit-able due to the definition of function t1 as
> "static inline" with its empty body. If I use instead of a class template a
> function template, this contained static local variable will be optimized-away,
> as expected.
> 
> [mschulze@teeth tst]$ cat test.cc
> static inline void t1(const char* s) {}
> 
> template <typename T>
> struct class_template {
>     class_template() {
>         static const char s[]="class_template";
>         t1(s);
>     }
> };
> 
> template <typename T>
> static inline void function_template() {
>         static const char s[]="function_template";
>         t1(s);
>     }
> 
> int main(int, char**) {
>     class_template<int> t;
>     function_template<int>();
>     return 0;
> }
> 
> I compiled the program with
[mschulze@teeth tst]$ g++ -Wall -Os    test.cc -o t

> [mschulze@teeth tst]$ g++ -v
> Using built-in specs.
> Target: i586-redhat-linux
> Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
> --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla
> --enable-bootstrap --enable-shared --enable-threads=posix
> --enable-checking=release --with-system-zlib --enable-__cxa_atexit
> --disable-libunwind-exceptions
> --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk
> --disable-dssi --enable-plugin
> --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre
> --enable-libgcj-multifile --enable-java-maintainer-mode
> --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib
> --with-ppl --with-cloog --with-tune=generic --with-arch=i586
> --build=i586-redhat-linux
> Thread model: posix
> gcc version 4.4.1 20090725 (Red Hat 4.4.1-2) (GCC)
> 
> and then I used the string program to list the contained strings.
> 
> [mschulze@teeth tst]$ strings t
> /lib/ld-linux.so.2
> libstdc++.so.6
> __gmon_start__
> _Jv_RegisterClasses
> __gxx_personality_v0
> libm.so.6
> libgcc_s.so.1
> libc.so.6
> _IO_stdin_used
> __libc_start_main
> CXXABI_1.3
> GLIBC_2.0
> PTRhP
> QVhD
> [^_]
> class_template
> [mschulze@teeth tst]$
> 
> The class_template string is present, but the function_template string not. If
> I omit the static keyword, it will disappear, too.
> 
> 
> 
> Thanks in advance,
> Michael
> 

Comment 2 Richard Biener 2010-06-18 10:51:08 UTC
9.4.2/6 says that static data members of a class have external linkage.  You
should be able to adjust that by providing proper visibility attributes
or pragmas.
Comment 3 Michael Schulze 2010-06-18 12:01:12 UTC
IMO, this is not a static member of a class itself, even it is defined inside of a member function, thus I think it has not to have external linkage.
Comment 4 Jonathan Wakely 2010-06-18 13:25:36 UTC
If class_template<int>::class_template is instantiated in another translation unit then it needs to refer to the same 's' ... but since the constructor calls a static function, an instantiation in another TU would violate the ODR, which would be undefined (no diagnostic required) so by that argument the compiler could assume no other instantiations and therefore no valid way for another TU to refer to 's'
Comment 5 tbsaunde 2015-12-28 00:21:40 UTC
gcc now removes class_template when optimizing so fixed.