-1

I've tried reading the C++ docs, but I find it so hard to follow. I like to zero initialise my structs like this:

MyStruct myStruct = {};

But if I have this struct as a class member, how do I zero initialise in the constructor?

struct MyStruct
{
 int x;
 int y;
}

class MyClass
{
 MyStruct mMyStruct;
public:
 MyClass();
} 



// is this fine?
MyClass::MyClass()
 : mMyStruct()
{}

// or this?
MyClass::MyClass()
 : mMyStruct({})
{}

// or do I need this?
MyClass::MyClass()
 : mMyStruct()
{
 mMyStruct = {};
}
Joe
  • 726
  • 1
  • 8
  • 18
  • Well, what happens when you tried that? – Sam Varshavchik Jun 06 '17 at 11:04
  • 3
    Why do you feel the compulsion to zero-initialize everything? If instances of a particular class should *always* be zero-initialized, then this should be done by the class's default constructor. – Cody Gray - on strike Jun 06 '17 at 11:04
  • 1
    You forgot one variant `MyClass() : myStruct{} {}` – Some programmer dude Jun 06 '17 at 11:04
  • 2
    This question is a subtle variant of [this one](https://stackoverflow.com/questions/27382036/zero-initialize-array-member-in-initialization-list). I could make a strong argument for them being duplicates, but not strong enough to exercise my unilateral voting power. – Cody Gray - on strike Jun 06 '17 at 11:06
  • @CodyGray: To me the question is a little too different. A `class` and an array are different beasts. (And the answer to this is pretty trivial. although a bit of a pig to type out on an iPhone 6 plus.) – Bathsheba Jun 06 '17 at 11:07
  • When you say "the C++ docs", which reference specifically are you using? And which book are you using to learn the language? – Lightness Races in Orbit Jun 06 '17 at 11:17
  • @Stargateur Added definitions of MyClass and MyStruct to the question. – Joe Jun 06 '17 at 11:18
  • @CodyGray "Why do you feel the compulsion to zero-initialize everything?" that's not the question I'm asking, classic Stackoverflow. – Joe Jun 06 '17 at 11:18
  • 2
    But since XY problems are so common, it's not unreasonable to check. – Useless Jun 06 '17 at 11:19
  • @BoundaryImposition I'm not learning from a book, I write C/C++ as my day job, but this is a hole in my knowledge which I wanted to sort out. I usually look things up on cppreference or cplusplus, so I'm not looking at the official C++ standard published by the committee. – Joe Jun 06 '17 at 11:19
  • 1
    @SamVarshavchik When I tried them, they all work, but a) VS is usually very forgiving about zero initialising things for you, but optimisation level can change this, and b) I want to make sure what I'm writing is correct and portable etc. – Joe Jun 06 '17 at 11:20
  • @Joe: The runtime library that ships with Visual Studio is usually very aggressive in filling memory with well-known patterns in debug mode, so that you immediately see failure to zero-initialize structures. – IInspectable Jun 06 '17 at 11:22
  • Which is why I posted a *comment*, rather than an answer, yo. If "Classic Stack Overflow" is you get expert feedback on things even if you didn't specifically ask about them, then I don't see how that's a bad thing. – Cody Gray - on strike Jun 06 '17 at 11:24
  • 1
    Using () or ({}) or {} makes a very subtlebut noticable difference when you have types with an initializer list constructor as member of your struct. In the last two cases, they will invoke that constructor, in the first case they will not (never, actually, unless the initializer list constructor has a default argument). – Johannes Schaub - litb Jun 06 '17 at 11:25
  • I am also unsure about what happens when you have reference members in your struct and you initialize the struct with {},. Hopefully it is an error, but since you can initialize a reference by {}, not necessarily. – Johannes Schaub - litb Jun 06 '17 at 11:27
  • @CodyGray yeah fair point. I'm zero initialising this struct because I like my structs to have no member functions, they're just data. Generally I write my C++ code in quite a Cish style, but I work in a large C++ codebase so I also have to work with existing classes etc. Hence I end up with a class which contains one of my structs. – Joe Jun 06 '17 at 11:31
  • @CodyGray and it's my understanding that the compiler generated default constructor of my struct will not zero initialise those int members because they're built in types? So I just want something to quickly and easily zero init, and {} is what I usually use. – Joe Jun 06 '17 at 11:39
  • Understand that () will not merely be a default constructor call, in many simple cases it won't even call the default constructor. – Johannes Schaub - litb Jun 06 '17 at 11:41
  • @JohannesSchaub-litb it won't? when does it not call the default constructor? – Joe Jun 06 '17 at 11:42
  • C doesn't zero-initialize the member variables of structs either, so I'm not sure how this is a C-ish style. I also follow the convention that `struct` means POD, while `class` means some type of more complex object, even though the keywords are technically interchangeable in C++. I don't see what that has to do with zero-initialization. At any rate, what I said was to write your *own* default constructor to zero-initialize the members. Of course the compiler won't do it. – Cody Gray - on strike Jun 06 '17 at 11:43
  • @CodyGray I write Cish C++ in that I don't use classes, I just have (functionless) structs, and functions, that's it. I use C++ because there's a few things there that I use occasionally like function overloading. The reason I don't give this struct a default constructor is that I don't put any functions in my structs, at all, ever. – Joe Jun 06 '17 at 11:48
  • @CodyGray did that answer satisfy you then 'expert'? ^_^ – Joe Jun 06 '17 at 22:43

2 Answers2

3

One way is:

class MyClass
{
    MyStruct mMyStruct = {};
public:
    MyClass();   // actually unnecessary
};
M.M
  • 138,810
  • 21
  • 208
  • 365
  • 2
    If it's unnecessary, don't write it. – Lightness Races in Orbit Jun 06 '17 at 12:12
  • @BoundaryImposition: There **are** valid reasons to write out superfluous code, e.g. for documentation purposes, or even just to have a line of code to set a breakpoint. – IInspectable Jun 06 '17 at 12:53
  • 2
    @IInspectable: If either of those cases come up, the code is no longer "superfluous" or "unnecessary" so the point becomes moot. – Lightness Races in Orbit Jun 06 '17 at 13:17
  • 1
    @BoundaryImposition If nobody wrote unnecessary things, this wouldn't be a comment. – Yakk - Adam Nevraumont Jun 06 '17 at 13:18
  • 1
    @Yakk: Not sure what you mean. – Lightness Races in Orbit Jun 06 '17 at 13:20
  • @BoundaryImposition Triple negative self undermining statement in the form of a standard debate disagreement. In theory, the humor comes from the delay between the seeming disagreement, and the effort in evaluating the 3x negative to work out the comment's self undermining claim. Not sure if that helps. – Yakk - Adam Nevraumont Jun 06 '17 at 13:32
  • 1
    I didn't come here for personal attacks, @IInspectable. Perhaps you could rephrase your comment so as to make your point without resorting to one? – Lightness Races in Orbit Jun 06 '17 at 15:18
  • @BoundaryImposition: Incidentally, I didn't. – IInspectable Jun 06 '17 at 15:32
  • @iins sorry I don't buy your argument. If the line of code makes things more convenient then it is not superfluous. If you argue about necessity, then please also state what for. No C++ code is necessary for having a binary that does something when you also could write assembly, as a simple example – Johannes Schaub - litb Jun 06 '17 at 17:03
  • @joha: The **code** ***is*** strictly unnecessary, even when it is convenient. And then it depends on who is sitting in front of the machine. If this is someone who has been exposed to debuggers with a graphical UI only, the convenience borders necessity. If this is someone, who has been using WinDbg for decades, that convenience may not even be obvious to them, because they always set breakpoints on symbols, and know how to translate C++ symbols into their mangled representation. The code is unnecessary for both, and not in the skewed *"you could use asm, too"* analogy sense. – IInspectable Jun 06 '17 at 17:13
1

You can use the notation

MyClass::MyClass()
 : mMyStruct{}
{
}

See http://en.cppreference.com/w/cpp/language/initializer_list

That documentation ain't so bad you know.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • 1
    Cool, but just because I'm curious, do either of the first 2 in my question work? – Joe Jun 06 '17 at 11:16
  • _"That documentation ain't so bad you know."_ Really? It's not exactly easy to follow, particularly for someone who isn't an expert in C++ standardese. Then again, one might say the same about the language itself! – Lightness Races in Orbit Jun 06 '17 at 11:18
  • @boundary the wiki has a discussion section. Please report your concerns there. I have seen many high profile users around there that will be happy to improve things. – Johannes Schaub - litb Jun 06 '17 at 11:21