Saya memiliki contoh kode di mana optimasi langsung tidak berfungsi ketika disusun sebagai variabel kelas, namun berfungsi sebagai variabel lokal; Saya ingin tahu: mengapa optimasi tidak terjadi pada formulasi variabel kelas?
Maksud dari kode contoh saya adalah untuk memiliki kelas yang diaktifkan atau dinonaktifkan saat konstruksi dan mungkin diubah selama masa pakainya. Saya berharap, ketika objek dinonaktifkan seumur hidupnya, kompiler akan mengoptimalkan semua kode yang dijalankan secara kondisional ketika objek diaktifkan.
Secara khusus, saya memiliki std::ofstream yang hanya ingin saya tulis ketika "diaktifkan". Saat dinonaktifkan, saya ingin semua output yang diformat dilewati. (Kelas saya yang sebenarnya melakukan pemformatan pesannya sendiri yang tidak sepele.)
Saya menemukan bahwa ketika saya merumuskan ini sebagai sebuah kelas, saya tidak mendapatkan optimasi yang saya harapkan. Namun, jika saya mereplikasi semua kode sebagai variabel lokal, saya melihat perilaku yang diharapkan.
Selain itu, saya menemukan bahwa jika saya tidak melakukan panggilan std::ofstream seperti 'buka', 'pengecualian', atau 'hapus' di mana pun di badan metode kelas contoh, saya juga mendapatkan pengoptimalan yang diharapkan. (Namun, desain saya mengharuskan melakukan panggilan seperti itu di std::ofstream, jadi bagi saya ini adalah poin yang bisa diperdebatkan.) Kode di bawah ini menggunakan MACRO DISABLE_OPEN_OFSTREAM_AFTER_CONSTRUCTOR untuk mengizinkan seseorang mencoba kasus ini.
Kode contoh saya menggunakan ekspresi 'asm' untuk memasukkan komentar ke dalam kode Majelis yang dihasilkan. Jika seseorang memeriksa output kompiler di Majelis, saya berharap tidak ada Majelis di antara komentar 'tes yang dinonaktifkan'. Saya mengamati pertemuan antara komentar 'tes nonaktif kelas', namun tidak ada pertemuan antara komentar 'tes nonaktif lokal'.
Masukkan kode C++:
#include <fstream> // ofstream
#define DISABLE_OPEN_OFSTREAM_AFTER_CONSTRUCTOR 0
class Test_Ofstream
{
public:
Test_Ofstream( const char a_filename[],
bool a_b_enabled )
#if DISABLE_OPEN_OFSTREAM_AFTER_CONSTRUCTOR
: m_ofstream( a_filename ),
m_b_enabled( a_b_enabled )
{
}
#else
: m_ofstream(),
m_b_enabled( a_b_enabled )
{
m_ofstream.open( a_filename );
}
#endif
void write_test()
{
if( m_b_enabled )
{
m_ofstream << "Some text.\n";
}
}
private:
std::ofstream m_ofstream;
bool m_b_enabled;
};
int main( int argc, char* argv[] )
{
{
Test_Ofstream test_ofstream( "test.txt", true );
asm( "# BEGIN class enabled-test" );
test_ofstream.write_test();
asm( "# END class enabled-test" );
}
{
Test_Ofstream test_ofstream( "test.txt", false );
asm( "# BEGIN class disabled-test" );
test_ofstream.write_test();
asm( "# END class disabled-test" );
}
{
bool b_enabled = true;
#if DISABLE_OPEN_OFSTREAM_AFTER_CONSTRUCTOR
std::ofstream test_ofstream( "test.txt" );
#else
std::ofstream test_ofstream;
test_ofstream.open( "test.txt" );
#endif
asm( "# BEGIN locals enabled-test" );
if( b_enabled )
{
test_ofstream << "Some text.\n";
}
asm( "# END locals enabled-test" );
}
{
bool b_enabled = false;
#if DISABLE_OPEN_OFSTREAM_AFTER_CONSTRUCTOR
std::ofstream test_ofstream( "test.txt" );
#else
std::ofstream test_ofstream;
test_ofstream.open( "test.txt" );
#endif
asm( "# BEGIN locals disabled-test" );
if( b_enabled )
{
test_ofstream << "Some text.\n";
}
asm( "# END locals disabled-test" );
}
return 0;
}
Kode perakitan keluaran:
##### Cut here. #####
#APP
# 53 "test_ofstream_optimization.cpp" 1
# BEGIN class disabled-test
# 0 "" 2
#NO_APP
cmpb $0, 596(%esp)
je .L22
movl $.LC1, 4(%esp)
movl %ebx, (%esp)
.LEHB9:
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
.LEHE9:
.L22:
#APP
# 55 "test_ofstream_optimization.cpp" 1
# END class disabled-test
# 0 "" 2
#NO_APP
##### Cut here. #####
#APP
# 116 "test_ofstream_optimization.cpp" 1
# BEGIN locals disabled-test
# 0 "" 2
# 121 "test_ofstream_optimization.cpp" 1
# END locals disabled-test
# 0 "" 2
#NO_APP
##### Cut here. #####
Saya menyadari bahwa ini mungkin terkait dengan kompiler yang saya gunakan, yaitu: g++-4.6 (Debian 4.6.1-4) 4.6.1; bendera kompiler: -Wall -S -O2. Namun, ini sepertinya optimasi yang sederhana. Saya merasa sulit untuk percaya bahwa kompilernya mungkin yang kacau.
Bantuan, wawasan, atau bimbingan apa pun sangat dihargai.