ฉันมีตัวอย่างของโค้ดที่การปรับให้เหมาะสมตรงไปตรงมาไม่ทำงานเมื่อมีโครงสร้างเป็นตัวแปรคลาส แต่ยังทำงานเป็นตัวแปรท้องถิ่น ฉันต้องการทราบ: เหตุใดการปรับให้เหมาะสมจึงไม่เกิดขึ้นในการกำหนดตัวแปรคลาส
จุดประสงค์ของโค้ดตัวอย่างของฉันคือการมีคลาสที่เปิดหรือปิดใช้งานระหว่างการก่อสร้างและอาจเปลี่ยนแปลงได้ตลอดอายุการใช้งาน ฉันคาดหวังว่าเมื่อวัตถุถูกปิดใช้งานตลอดอายุการใช้งาน คอมไพเลอร์จะปรับโค้ดทั้งหมดที่ดำเนินการตามเงื่อนไขเมื่อเปิดใช้งานวัตถุให้เหมาะสม
โดยเฉพาะฉันมี std::ofstream ที่ฉันต้องการเขียนเมื่อ "เปิดใช้งาน" เท่านั้น เมื่อปิดใช้งาน ฉันต้องการให้ข้ามเอาต์พุตที่ฟอร์แมตแล้วทั้งหมด (ชั้นเรียนจริงของฉันมีการจัดรูปแบบข้อความเป็นของตัวเองโดยไม่สำคัญ)
ฉันค้นพบว่าเมื่อฉันกำหนดสิ่งนี้เป็นคลาส ฉันไม่ได้รับการปรับให้เหมาะสมตามที่คาดหวัง อย่างไรก็ตาม หากฉันจำลองโค้ดทั้งหมดเป็นตัวแปรในเครื่อง ฉันจะเห็นลักษณะการทำงานที่คาดไว้
นอกจากนี้ ฉันค้นพบว่าหากฉันไม่ทำการเรียก std::ofstream เช่น 'open', 'ข้อยกเว้น' หรือ 'ล้าง' ที่ใดก็ได้ในเนื้อความของเมธอดของคลาสตัวอย่าง ฉันจะได้รับการปรับให้เหมาะสมตามที่คาดหวังไว้ด้วย (อย่างไรก็ตาม การออกแบบของฉันต้องการทำการเรียกดังกล่าวบน std::ofstream ดังนั้นสำหรับฉันมันเป็นจุดที่สงสัย ) โค้ดด้านล่างใช้ MACRO DISABLE_OPEN_OFSTREAM_AFTER_CONSTRUCTOR เพื่ออนุญาตให้ลองใช้เคสนี้
โค้ดตัวอย่างของฉันใช้นิพจน์ 'asm' เพื่อแทรกความคิดเห็นลงในโค้ดแอสเซมบลีที่สร้างขึ้น หากใครตรวจสอบผลลัพธ์ของคอมไพเลอร์ในชุดประกอบ ฉันคาดว่าจะไม่มีการประกอบระหว่างความคิดเห็น 'การทดสอบที่ปิดใช้งาน' ฉันกำลังสังเกตการชุมนุมระหว่างความคิดเห็น 'การทดสอบปิดการใช้งานคลาส' แต่ไม่มีการชุมนุมระหว่างความคิดเห็น 'การทดสอบปิดการใช้งานในท้องถิ่น'
รหัสอินพุต 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;
}
รหัสแอสเซมบลีเอาต์พุต:
##### 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. #####
ฉันรู้ว่านี่อาจเชื่อมโยงกับคอมไพเลอร์ที่ฉันใช้ซึ่งก็คือ: g++-4.6 (Debian 4.6.1-4) 4.6.1; ธงคอมไพเลอร์: -Wall -S -O2 อย่างไรก็ตาม ดูเหมือนว่าเป็นการเพิ่มประสิทธิภาพที่เรียบง่าย ฉันพบว่ามันยากที่จะเชื่อว่าคอมไพเลอร์อาจเกิดปัญหาได้
ความช่วยเหลือ ข้อมูลเชิงลึก หรือคำแนะนำใด ๆ ที่ได้รับการชื่นชมอย่างมาก