Are empty constructors always called in C++?

China☆狼群 提交于 2019-12-04 04:46:38

When in optimizing mode, if your class or structure is POD (has only POD types) and constructor is not specified, any production quality C++ compiler will not only skip the call to a constructor but not even generate it.

If your class has non-POD members who's constructor(s) have to be called, compiler will generate default constructor that calls member's constructors. But even then - it will not initialize POD types. I.e. if you don't initialize member explicitly, you may end up with garbage there.

The whole thing can get even fancies if your compiler/linker has LTO.

Hope it helps! And make your program work first, then use a profiler to detect slow places, then optimize it. Premature optimization may not only make your code unreadable and waste tons of your time, but could also not help at all. You have to know what to optimize first.

Here is a disassembly for code in your example (x86_64, gcc 4.4.5):

main:
    subq    $8, %rsp
    movl    $4, %edi
    call    _Znwm
    movl    $4, %edi
    movl    $0, (%rax)
    call    _Znwm
    movl    $4, %edi
    movl    $0, (%rax)
    call    _Znwm
    movl    $400, %edi
    movl    $3, (%rax)
    call    _Znam
    xorl    %eax, %eax
    addq    $8, %rsp
    ret

As you can see, there are no constructors called at all. There are no classes at all, every object is just a 4 bytes integer.

With MS compiler, YMMV. So you have to check disassembly yourself. But result should be similar.

Good luck!

will a compiler generated constructor/empty constructor always be called when you instantiate an object?

No. If your class is a so-called “POD” (plain old data) then the compiler-generated constructor won’t always be called.

Specifically, it won’t be called in the two following cases:

struct Pod {
    int x;
};

int main() {
    Pod pod;
    std::cout << pos.x << std::endl; // Value undefined.

    Pod pod2 = Pod(); // Explicit value initialization.


    Pod* pods = new Pod[10];
    // Values of `pods` undefined.

    Pod* pods2 = new Pod[10](); // Explicit value initialization.
}

The conditions for when exactly a type is a POD are a bit tricky. The C++ FAQ has a nice breakdown.

Logically, the constructor is called. In generated code, if the constructor does nothing, there will be no instructions that can be traced back to the constructor, unless your compiler is very very bad at optimizing and inserts a call to something that just returns.

Certain class or struct types are called POD "Plain Old Data" in C++. These types will not have constructors called.

The rules for being a POD are important enough that you should look them up, but in summary: only contains primitive data types and has no defined constructors.

Your sample isn't very good, you've missed the public keyword in sample classes and moreover in your examples force zero-initialization by writing CLASS * class = new CLASS(); instead of CLASS * class = new CLASS;.

In the code as you put it - zero-initialization will always be performed as it is required by the standard. You can call it as you want - but there WILL be code to guarantee the rules of the standard.

If you had asked without showing this controversial sample code - then the only correct answer would be - compiler specific.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!