Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Zeroing in the constructor

267 views
Skip to first unread message

Noob

unread,
Jun 12, 2015, 4:55:10 PM6/12/15
to
Hello,

I've taken a look at a medium-sized C++ legacy code-base which
crashes in several places. (NB: I'm a C coder.)

Turns out the program defines several large classes (~50 fields,
mostly int's or int arrays, and a few pointers). The constructor
is supposed to set everything to 0s and NULLs, but it misses a
few fields, and the program blows up when it uses one of these
uninitialized fields.

I was thinking: instead of trying to figure out which fields
are missing in the constructor, I could just bulldoze the
entire object:

std::memset(this, 0, sizeof *this);

(The code doesn't use the virtual keyword anywhere.)

Will this work as expected?

Regards.

Victor Bazarov

unread,
Jun 12, 2015, 5:20:41 PM6/12/15
to
You could, and we used to do that. However such practice is frowned
upon. So, don't tell anybody and put lots of warnings in the header not
to add any virtual functions or else!

However, in terms of software engineering, I believe it would actually
be better to add the missing initializers and also add verification (of
the same sort, like memcmp or whatever is available) and throw an
exception if the verification does not pass.

V
--
I do not respond to top-posted replies, please don't ask

Richard

unread,
Jun 12, 2015, 7:03:13 PM6/12/15
to
[Please do not mail me a copy of your followup]

Noob <ro...@127.0.0.1> spake the secret code
<mlfgso$f84$1...@dont-email.me> thusly:

>I was thinking: instead of trying to figure out which fields
>are missing in the constructor, I could just bulldoze the
>entire object:
>
> std::memset(this, 0, sizeof *this);

Please don't do this.

Instead crank up the warning level on your compiler to have it tell you
which members are uninitialized.

#include <iostream>

class A
{
public:
A()
: f()
{}

int get_f() { return f; }
int get_g() { return g; }

private:
int f;
int g;
};

int main()
{
A a;
std::cout << "f = " << a.get_f() << "\n"
<< "g = " << a.get_g() << "\n";
}

shell 161> g++ -Weffc++ /tmp/a.cpp
/tmp/a.cpp: In constructor 'A::A()':
/tmp/a.cpp:6:2: warning: 'A::g' should be initialized in the member
initialization list [-Weffc++]
A()
^

Tools like cppcheck can also identify uninitialized members of a
class. <http://cppcheck.sourceforge.net/>
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

Ian Collins

unread,
Jun 12, 2015, 7:31:03 PM6/12/15
to
Richard wrote:
>
> shell 161> g++ -Weffc++ /tmp/a.cpp

A gcc option that breaks google :)

Your search - -Weffc++ - did not match any documents.

--
Ian Collins
Message has been deleted

Victor Bazarov

unread,
Jun 12, 2015, 7:56:42 PM6/12/15
to
On 6/12/2015 7:39 PM, Stefan Ram wrote:
> Ian Collins <ian-...@hotmail.com> writes:
>> Richard wrote:
>>> shell 161> g++ -Weffc++ /tmp/a.cpp
>> A gcc option that breaks google :)
>> Your search - -Weffc++ - did not match any documents.
>
> It only »breaks« the expectations of Google users who did
> not study the Google operators manual before using the Google
> »-« operator in their Google search specifications.

Pfft! Real programmers never read manuals! ;-)

Richard

unread,
Jun 12, 2015, 8:15:12 PM6/12/15
to
[Please do not mail me a copy of your followup]

Ian Collins <ian-...@hotmail.com> spake the secret code
<cu18db...@mid.individual.net> thusly:

>Richard wrote:
>>
>> shell 161> g++ -Weffc++ /tmp/a.cpp
>
>A gcc option that breaks google :)
>
> Your search - -Weffc++ - did not match any documents.

<http://bfy.tw/JZU>

Noob

unread,
Jun 13, 2015, 4:58:07 AM6/13/15
to
On 13/06/2015 01:03, Richard wrote:

> Noob wrote:
>
>> I was thinking: instead of trying to figure out which fields
>> are missing in the constructor, I could just bulldoze the
>> entire object:
>>
>> std::memset(this, 0, sizeof *this);
>
> Please don't do this.
>
> Instead crank up the warning level on your compiler to have it tell you
> which members are uninitialized.

You don't say why the latter is better?

The current constructor is ~60 lines of code.

In my (predominantly C) experience, clearing the entire struct with
a single line communicates the intent more clearly, which results in
less maintenance over time.

Are you concerned about complex classes (with virtual inheritance,
and perhaps other features)?

If we are talking about a plain struct, there are no problems, right?

(Although I seem to recall that C++'s "struct" is just a synonym for
"class" with everything public.)

If the class consists only of int fields + accessors, are there
unforeseen drawbacks to zeroing with memset?

(Thanks for the -Weffc++ flasg nonetheless)

Regards.

Christian Gollwitzer

unread,
Jun 13, 2015, 5:14:09 AM6/13/15
to
Am 12.06.15 um 22:54 schrieb Noob:
> I've taken a look at a medium-sized C++ legacy code-base which
> crashes in several places. (NB: I'm a C coder.)
>
> Turns out the program defines several large classes (~50 fields,
> mostly int's or int arrays, and a few pointers). The constructor
> is supposed to set everything to 0s and NULLs, but it misses a
> few fields, and the program blows up when it uses one of these
> uninitialized fields.
>


The best way to debug such things is a memory checker. If you can
compile your code on Linux, then valgrind is the best tool you can ever
have. It will tell you which fields have been red without prior
initialization. Tools for other platforms exist, too. I think Visual C++
has a compiler flag to catch these things. And, if the culprit is really
the constructor, even the compiler can issue a warning with the highest
warning level.

Christian

Christian Gollwitzer

unread,
Jun 13, 2015, 5:32:45 AM6/13/15
to
Am 13.06.15 um 10:57 schrieb Noob:
> On 13/06/2015 01:03, Richard wrote:
>
>> Noob wrote:
>>
>>> I was thinking: instead of trying to figure out which fields
>>> are missing in the constructor, I could just bulldoze the
>>> entire object:
>>>
>>> std::memset(this, 0, sizeof *this);
>>
>> Please don't do this.
>>
>> Instead crank up the warning level on your compiler to have it tell you
>> which members are uninitialized.
>
> You don't say why the latter is better?
>
> The current constructor is ~60 lines of code.
>
> In my (predominantly C) experience, clearing the entire struct with
> a single line communicates the intent more clearly, which results in
> less maintenance over time.

That's because C doesn't have the concept of initialization at all. You
can just assign something. The constructor/destructor pair gives rise to
one of the most powerful mechanisms in C++ (RAII)

>
> Are you concerned about complex classes (with virtual inheritance,
> and perhaps other features)?

Setting the bits to zero discards the type information. The compiler has
no way to check that for you. For instance, it is not guaranteed even
for a simple float, that all zero bits denotes 0.0 and not some odd
value (true for IEEE floats, but...). For real complicated cases this
matters, as you say, classes with virtual functions get likely
destroyed, because you overwrite the pointer to the VTable. If there are
more complex members, like a std::vector, then it is properly
constructed by a real constructor. As soon as somebody modifies the
class and includes some of these, the code will magically break

> (Although I seem to recall that C++'s "struct" is just a synonym for
> "class" with everything public.)

Yes that is right. If you are worried about the amount of code: How do
you currently initialize your variables? Assign them in the body of the
constructor? There is a special initialization syntax for constructors:

class SomeClass {
public:
SomeClass() : value(5) {}
explicit SomeClass(int new_value) : value(new_value) {}

private:
int value;
};


and in C++11 it is even easier:

class SomeClass {
public:
SomeClass() {}
explicit SomeClass(int new_value) : value(new_value) {}

private:
int value = 5;
};


You could do that for all of your fields at the point where they are
declared, so would be easy to spot a missing one.

Christian

Marcel Mueller

unread,
Jun 13, 2015, 5:54:17 AM6/13/15
to
On 12.06.15 22.54, Noob wrote:
> I was thinking: instead of trying to figure out which fields
> are missing in the constructor, I could just bulldoze the
> entire object:
>
> std::memset(this, 0, sizeof *this);

This is guaranteed to work if and only if your class is a POD type, i.e.
it consists only of built-in data types like int, float, pointer etc. or
other POD types in all instance attributes and it neither has a custom
constructor nor private or protected instance attributes.

> Will this work as expected?

Well, in real live on most platforms the condition above is slightly
relaxed. I.e. it may also inherit (non-virtual) from a POD type, and
neither a custom constructor nor protected attributes cause any harm.

To come around the undefined behavior according to the C++ standard you
can do a trick: split your class into a POD base type and a non POD
derived type.

struct myPOD
{ int SomeInt;
AnotherClass* Pointer;
//...
};

class myPODWrapper : public myPOD
{
myPODWrapper()
{ memset(static_cast<myPOD*>(this), 0, sizeof(myPOD));
}
};

Now you are perfectly save. You only access the POD base type in a C
style manner. (Note the static cast which does the slicing.)
The derived type does no longer have any restrictions. It also may have
virtual functions and whatever you like.
The type myPODWrapper implicitly converts to myPOD and my be flawlessly
used for C API calls. The only critical thing are downcasts. They are
necessary when a C callback gives you only the POD type pointer. In this
case you need to be absolutely sure that you only get the pointers that
/you/ passed to the API and not a value copy of the POD slice.

I have used this pattern many times to wrap C APIs more safely by simply
deriving from their struct types in the C headers. It usually works as
long as the API let you allocate the storage for the PODs.


Marcel

Luca Risolia

unread,
Jun 13, 2015, 7:51:22 AM6/13/15
to
Il 12/06/2015 22:54, Noob ha scritto:
> Turns out the program defines several large classes (~50 fields,
> mostly int's or int arrays, and a few pointers). The constructor
> is supposed to set everything to 0s and NULLs
>
> std::memset(this, 0, sizeof *this);

> Will this work as expected?

No, unless you make your classes POD types first. Since you said they
define a constructor, they are not POD-classes. To check if a class is a
POD type the standard provides std::is_pod<>.

Noob

unread,
Jun 13, 2015, 12:28:32 PM6/13/15
to
On 13/06/2015 01:30, Ian Collins wrote:

> Richard wrote:
>
>> shell 161> g++ -Weffc++ /tmp/a.cpp
>
> A gcc option that breaks google :)
>
> Your search - -Weffc++ - did not match any documents.

https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html#index-Weffc_002b_002b-212

-Weffc++ (C++ and Objective-C++ only)

Warn about violations of the following style guidelines from Scott Meyers' Effective C++ series of books:

Define a copy constructor and an assignment operator for classes with dynamically-allocated memory.
Prefer initialization to assignment in constructors.
Have operator= return a reference to *this.
Don't try to return a reference when you must return an object.
Distinguish between prefix and postfix forms of increment and decrement operators.
Never overload &&, ||, or ,.

This option also enables -Wnon-virtual-dtor, which is also one of the effective C++ recommendations. However, the check is extended to warn about the lack of virtual destructor in accessible non-polymorphic bases classes too.

When selecting this option, be aware that the standard library headers do not obey all of these guidelines; use ‘grep -v’ to filter out those warnings.

Noob

unread,
Jun 13, 2015, 12:36:55 PM6/13/15
to
On 13/06/2015 11:54, Marcel Mueller wrote:

> On 12.06.15 22.54, Noob wrote:
>
>> I was thinking: instead of trying to figure out which fields
>> are missing in the constructor, I could just bulldoze the
>> entire object:
>>
>> std::memset(this, 0, sizeof *this);
>
> This is guaranteed to work if and only if your class is a POD type, i.e.
> it consists only of built-in data types like int, float, pointer etc. or
> other POD types in all instance attributes and it neither has a custom
> constructor nor private or protected instance attributes.

What's a _custom_ constructor?
Is it merely an explicitly defined constructor?

> Well, in real live on most platforms the condition above is slightly
> relaxed. I.e. it may also inherit (non-virtual) from a POD type, and
> neither a custom constructor nor protected attributes cause any harm.
>
> To come around the undefined behavior according to the C++ standard you
> can do a trick: split your class into a POD base type and a non POD
> derived type.

The objects only contain ints, int arrays, bools, and raw pointers
to other program-defined classes, so it is already POD, AFAIU right?

> struct myPOD
> { int SomeInt;
> AnotherClass* Pointer;
> //...
> };
>
> class myPODWrapper : public myPOD
> {
> myPODWrapper()
> { memset(static_cast<myPOD*>(this), 0, sizeof(myPOD));
> }
> };
>
> Now you are perfectly save. You only access the POD base type in a C
> style manner. (Note the static cast which does the slicing.)
> The derived type does no longer have any restrictions. It also may have
> virtual functions and whatever you like.
> The type myPODWrapper implicitly converts to myPOD and my be flawlessly
> used for C API calls. The only critical thing are downcasts. They are
> necessary when a C callback gives you only the POD type pointer. In this
> case you need to be absolutely sure that you only get the pointers that
> /you/ passed to the API and not a value copy of the POD slice.
>
> I have used this pattern many times to wrap C APIs more safely by simply
> deriving from their struct types in the C headers. It usually works as
> long as the API let you allocate the storage for the PODs.

Thanks, I will look a bit closer at the code.

Regards.

Noob

unread,
Jun 13, 2015, 1:33:32 PM6/13/15
to
On 13/06/2015 11:32, Christian Gollwitzer wrote:

> Setting the bits to zero discards the type information. The compiler has
> no way to check that for you. For instance, it is not guaranteed even
> for a simple float, that all zero bits denotes 0.0 and not some odd
> value (true for IEEE floats, but...).

I'm not sure what you meant by "discards the type information".

In C too, it is not guaranteed that all-bits-0 pattern is 0.0 or NULL.

> Yes that is right. If you are worried about the amount of code: How do
> you currently initialize your variables? Assign them in the body of the
> constructor? There is a special initialization syntax for constructors:

Just to be clear: this is a medium-sized project (100 kLOC) that
someone else wrote for Windows. I am just porting it to Linux,
and a few bugs need fixing along the way. Hopefully, these
fixes are non intrusive! I don't want to rewrite the project.

> class SomeClass {
> public:
> SomeClass() : value(5) {}
> explicit SomeClass(int new_value) : value(new_value) {}
>
> private:
> int value;
> };

Your example is nice with 1 field. But the actual definition
is more like this:

class foo {
public:
int aa, bb, cc, ...
int va[Na], vb[Nb], ...
int v2a[N2a][Ma], v2b[N2b][Mb], ...
bar *p1, baz *p2, ...

foo();
~foo();
40 methods
};

Would it still look simple then?

> and in C++11 it is even easier:
>
> class SomeClass {
> public:
> SomeClass() {}
> explicit SomeClass(int new_value) : value(new_value) {}
>
> private:
> int value = 5;
> };

Do g++ and Visual Studio support this syntax?

> You could do that for all of your fields at the point where they are
> declared, so would be easy to spot a missing one.

Thanks for the suggestion.

(However, I'm afraid of the code churn, as it would mean
touching all the class definitions.)

Regards.

Marcel Mueller

unread,
Jun 14, 2015, 10:56:42 AM6/14/15
to
On 13.06.15 18.36, Noob wrote:
> What's a _custom_ constructor?
> Is it merely an explicitly defined constructor?

Exactly.

> The objects only contain ints, int arrays, bools, and raw pointers
> to other program-defined classes, so it is already POD, AFAIU right?

No, because they have a constructor.

But if you do not need platform independent code, e.g. because you are
stuck to some platform for other reasons, you might just check whether
this platform supports this.


Marcel

Richard

unread,
Jun 14, 2015, 11:36:33 PM6/14/15
to
[Please do not mail me a copy of your followup]

Noob <ro...@127.0.0.1> spake the secret code
<mlgr7t$5o0$1...@dont-email.me> thusly:

>On 13/06/2015 01:03, Richard wrote:
>
>> Noob wrote:
>>
>>> I was thinking: instead of trying to figure out which fields
>>> are missing in the constructor, I could just bulldoze the
>>> entire object:
>>>
>>> std::memset(this, 0, sizeof *this);
>>
>> Please don't do this.
>>
>> Instead crank up the warning level on your compiler to have it tell you
>> which members are uninitialized.
>
>You don't say why the latter is better?

At the risk of repeating myself once again: please stop writing C style
code in a C++ program. C++ is not C, it is a different language that
provides a large amount of interoperability with C code, but it is not
C.

std::memset is the way that C zeroes a chunk of bytes. If those chunk
of bytes happen to be a structure layout for which "initialized" is
the same thing as setting all the bytes in the structure to zero, then
it can be thought of as "initializing" the structure. (This is often
not the case, even in C; members of the structure may need to be set
to something other than zero in order to be consistent with the
preconditions of the data structure.)

C++ uses constructors to guarantee that an object, once constructed,
is ready for use and that all the invariants of the object have been
established. Constructors don't return error codes.

If the invariants can't be established by the constructor, then it is
common for the constructor to throw an exception, guaranteeing that you
either get a valid object, or nothing.

>The current constructor is ~60 lines of code.

So?

>In my (predominantly C) experience,

This isn't C. This is C++. C++ != C.

>clearing the entire struct with
>a single line communicates the intent more clearly, which results in
>less maintenance over time.

The reason this is the accepted idiom in C is because C doesn't have
constructors and can't establish invariants for an object represented
by a struct.

Constructors establish that intent explicitly in the language,
instead of idiomatically by some sort of agreed upon convention.
Constructors reveal the intent of initialization more clearly than C
because it is a proper construct in the language.

>If we are talking about a plain struct, there are no problems, right?

As already mentioned on this thread, you have a class with a non-trivial
constructor. It is already not a "plain old data" struct like those in C.
See section 8.2.6 Plain Old Data in "The C++ Programming Language",
Bjarne Stroustrup, 4th ed., pg. 210:

"For example, copying a 100-element array using 100 calls of a
copy constructor is unlikely to be as fast as calling std::memcpy(),
which typically simply uses a block-move machine instruction.
Even if the constructor is inlined, it could be hard for an
optimizer to discover this optimization. Such "tricks" are not
uncommon, and are important, in implementations of containers,
such as vector, and in low-level I/O routines.

**They are unnecessary and should be avoided in higher-level code.**"
(emphasis added.)

>(Although I seem to recall that C++'s "struct" is just a synonym for
>"class" with everything public.)

However, C++'s struct is not C's struct.

>If the class consists only of int fields + accessors, are there
>unforeseen drawbacks to zeroing with memset?

Yes, C++ provides explicit mechanisms for initialization and you
should use those and not C-style mechanisms. Initialization syntax
follows the "open/closed principle" of object-oriented design, but
std::memset does not.

Christian Gollwitzer

unread,
Jun 15, 2015, 1:10:45 AM6/15/15
to
Am 13.06.15 um 19:33 schrieb Noob:
> On 13/06/2015 11:32, Christian Gollwitzer wrote:
>
>> Setting the bits to zero discards the type information. The compiler has
>> no way to check that for you. For instance, it is not guaranteed even
>> for a simple float, that all zero bits denotes 0.0 and not some odd
>> value (true for IEEE floats, but...).
>
> I'm not sure what you meant by "discards the type information".
>
> In C too, it is not guaranteed that all-bits-0 pattern is 0.0 or NULL.

Yes, exactly. Wouldn't it be much nicer to initialize to a knwon value,
e.g. 0.0 or 3.14159... instead of just zero bits, which could be
anything, though in practice it's a sensible value for most data types?
Well the syntax would then be something like

foo() : aa(0), bb(0), ... { code }

simple or not, your choice. But surely that "class" is not idiomatic
C++. These odd integer arrays, are Na, Nb big numbers? If so, you'd be
better off using a std:vector for memory management. Raw pointers to
other structures also look suspicious. Your constructor should probably
establish a link to a real object, maybe construct one, and dispose it
in the destructor (or decrese the refcount or similar)


>> and in C++11 it is even easier:
>>
>> class SomeClass {
>> public:
>> SomeClass() {}
>> explicit SomeClass(int new_value) : value(new_value) {}
>>
>> private:
>> int value = 5;
>> };
>
> Do g++ and Visual Studio support this syntax?

They should, depends on the version, since this is a C++11 feature.
Should be no problem if you use a current version.

>> You could do that for all of your fields at the point where they are
>> declared, so would be easy to spot a missing one.
>
> Thanks for the suggestion.
>
> (However, I'm afraid of the code churn, as it would mean
> touching all the class definitions.)

Your choice, depends on whether it's cheaper to fix the engine using
chewing gum and shoelace, or doing it right and spending lots of time to
have it running for years.

Christian

>
> Regards.
>

Noob

unread,
Jun 15, 2015, 2:08:47 AM6/15/15
to
On 13/06/2015 11:32, Christian Gollwitzer wrote:

> and in C++11 it is even easier:
>
> class SomeClass {
> public:
> SomeClass() {}
> explicit SomeClass(int new_value) : value(new_value) {}
>
> private:
> int value = 5;
> };
>
>
> You could do that for all of your fields at the point where they are
> declared, so would be easy to spot a missing one.

What is the equivalent syntax for 0 initializing an int array?

int array[20] = { 0 };

like in C?

Also, can I omit the SomeClass(int) constructor if I don't
use it?

And can I omit the SomeClass() constructor, or does it have
to be defined to a NOP?

Regards.

Juha Nieminen

unread,
Jun 15, 2015, 4:41:53 AM6/15/15
to
Noob <ro...@127.0.0.1> wrote:
> In my (predominantly C) experience, clearing the entire struct with
> a single line communicates the intent more clearly, which results in
> less maintenance over time.

It may also break the class in the future, if somebody adds a new
member to it that requires its own construction (and which would just
break if you zero all of its bits).

// Current version of your class:
class MyClass
{
int a, b, c, d;
double e, f, g;

public:
MyClass() { std::memset(...); }
};

// Future version of your class:
class MyClass
{
int a, b, c, d;
double e, f, g;
std::string str; // might break, depending on implementation

public:
MyClass() { std::memset(...); }
};

If you can use C++11, it's better to initialize all the members where
they are declared (rather than in the constructor). This makes it a lot
more obvious if a member is not being initialized.

--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---

Richard

unread,
Jun 15, 2015, 10:35:15 AM6/15/15
to
[Please do not mail me a copy of your followup]

Noob <ro...@127.0.0.1> spake the secret code
<mllq2n$sff$1...@dont-email.me> thusly:

>On 13/06/2015 11:32, Christian Gollwitzer wrote:
>
>> and in C++11 it is even easier:
>>
>> class SomeClass {
>> public:
>> SomeClass() {}
>> explicit SomeClass(int new_value) : value(new_value) {}
>>
>> private:
>> int value = 5;
>> };
>>
>>
>> You could do that for all of your fields at the point where they are
>> declared, so would be easy to spot a missing one.
>
>What is the equivalent syntax for 0 initializing an int array?
>
> int array[20] = { 0 };

Value initialization:
<http://en.cppreference.com/w/cpp/language/value_initialization>

Vir Campestris

unread,
Jun 15, 2015, 4:43:43 PM6/15/15
to
On 15/06/2015 07:08, Noob wrote:
> What is the equivalent syntax for 0 initializing an int array?
>
> int array[20] = { 0 };
>
> like in C?

I've just been cursing GCC over this. We have warnings-as-errors and
warnings turned up full. It then complains that I haven't initialised
all the elements. (in my case it's a struct, not an int)

Andy.

Victor Bazarov

unread,
Jun 15, 2015, 4:51:23 PM6/15/15
to
Drop the 0 from between the curly braces. Is it happier now?

Noob

unread,
Jun 16, 2015, 2:48:06 PM6/16/15
to
On 15/06/2015 16:35, Richard wrote:

> Noob wrote:
>
>> On 13/06/2015 11:32, Christian Gollwitzer wrote:
>>
>>> and in C++11 it is even easier:
>>>
>>> class SomeClass {
>>> public:
>>> SomeClass() {}
>>> explicit SomeClass(int new_value) : value(new_value) {}
>>>
>>> private:
>>> int value = 5;
>>> };
>>>
>>>
>>> You could do that for all of your fields at the point where they are
>>> declared, so would be easy to spot a missing one.
>>
>> What is the equivalent syntax for 0 initializing an int array?
>>
>> int array[20] = { 0 };
>
> Value initialization:
> <http://en.cppreference.com/w/cpp/language/value_initialization>

I don't see the syntax suggested by Christian (type field_name = init_val;)
in cppreference's grammar?

I wrote the following test program:

class foo {
public:
int i = 5;
int array[5] = { 1, 2, 3 };
int uninit[100];
};

int main(void)
{
foo xx;
foo *yy = new foo;
foo *zz = new foo{};
foo *tt = new foo[20]{};
return xx.i + yy->i + zz->i + tt->i;
}

$ g++ -std=c++11 -Wall -Wextra -ggdb3 init.cpp

(I note that c++11 support was considered incomplete and experimental
in gcc 4.8)

The "uninit" array seems to be initialized to 0 in all cases
except xx. Is that by design or an accident of the allocator's
design?

What is the difference between new foo; and new foo{}; ?

Regards.

Victor Bazarov

unread,
Jun 16, 2015, 2:59:48 PM6/16/15
to
On 6/16/2015 2:47 PM, Noob wrote:
>[..]
> What is the difference between new foo; and new foo{}; ?

'new foo' default-initializes the object, 'new foo{}' performs the so
called direct-initialization. They differ a bit. The one without the
braces looks for a c-tor that can be called without the arguments, and
if found, calls it. If none exist, it leaves the object uninitialized!
The form with braces default-initializes the object, which in absence of
any c-tors yet with member initializers, performs member-wise
initialization using the initializers provided for each member.

IOW, 'new foo' ignores the individuals member initializers while 'new
foo{}' uses those.

Richard

unread,
Jun 16, 2015, 3:04:55 PM6/16/15
to
[Please do not mail me a copy of your followup]

Noob <ro...@127.0.0.1> spake the secret code
<mlpqub$tik$1...@dont-email.me> thusly:

>On 15/06/2015 16:35, Richard wrote:
>
>> Noob wrote:
>>
>>> On 13/06/2015 11:32, Christian Gollwitzer wrote:
>>>
>>>> and in C++11 it is even easier:
>>>>
>>>> class SomeClass {
>>>> public:
>>>> SomeClass() {}
>>>> explicit SomeClass(int new_value) : value(new_value) {}
>>>>
>>>> private:
>>>> int value = 5;
>>>> };
>>>>
>>>>
>>>> You could do that for all of your fields at the point where they are
>>>> declared, so would be easy to spot a missing one.
>>>
>>> What is the equivalent syntax for 0 initializing an int array?
>>>
>>> int array[20] = { 0 };
>>
>> Value initialization:
>> <http://en.cppreference.com/w/cpp/language/value_initialization>
>
>I don't see the syntax suggested by Christian (type field_name = init_val;)
>in cppreference's grammar?

<http://en.cppreference.com/w/cpp/language/data_members>

>I wrote the following test program:
>
>class foo {
> public:
> int i = 5;
> int array[5] = { 1, 2, 3 };
> int uninit[100];
>};
>
>int main(void)
>{
> foo xx;
> foo *yy = new foo;
> foo *zz = new foo{};
> foo *tt = new foo[20]{};
> return xx.i + yy->i + zz->i + tt->i;
>}
>
>$ g++ -std=c++11 -Wall -Wextra -ggdb3 init.cpp
>
>(I note that c++11 support was considered incomplete and experimental
>in gcc 4.8)
>
>The "uninit" array seems to be initialized to 0 in all cases
>except xx. Is that by design or an accident of the allocator's
>design?

This is probably coming from the allocator and the fact that in your
small program you haven't released any previously allocated memory back
to the allocator for reuse. All memory obtained from the operating
system (in modern operating systems, anyway) is zeroed before being
given to the allocator in the C++ runtime.

>What is the difference between new foo; and new foo{}; ?

They both invoke the default constructor, so I'd say nothing.

Noob

unread,
Jun 16, 2015, 4:16:32 PM6/16/15
to
On 16/06/2015 21:04, Richard wrote:

> This is probably coming from the allocator and the fact that in your
> small program you haven't released any previously allocated memory back
> to the allocator for reuse. All memory obtained from the operating
> system (in modern operating systems, anyway) is zeroed before being
> given to the allocator in the C++ runtime.

I refined the test program.

#include <cstring>
#include <cstdio>

class foo {
public:
int i = 42;
int v[5] = { 1, 2, 3 };
int uninit[100];
};

#define SIZE (1<<16)

static void dump(foo *p)
{
printf("%d %d %d %x\n", p->i, p->v[2], p->v[4], p->uninit[12]);
}

int main(void)
{
char *mem = new char[SIZE]; std::memset(mem, 0x1, SIZE); delete[] mem;
foo xxa;
foo xxb{};
foo *xxc = new foo;
foo *xxd = new foo();
foo *xxe = new foo{};
foo *xxf = new foo[20]{};
foo *xxg = new foo[20];
dump(&xxa); dump(&xxb); dump(xxc); dump(xxd); dump(xxe); dump(xxf+3); dump(xxg+7);
return 0;
}

$ g++ -std=c++11 -Wall -Wextra -ggdb3 init.cpp
$ ./a.out
42 3 0 f76bbc10
42 3 0 0
42 3 0 1010101
42 3 0 0
42 3 0 0
42 3 0 0
42 3 0 1010101

So the syntax for xxa, xxc, xxg leaves "uninit" uninitialized, while the
syntax for xxb, xxd, xxe, xxf 0-initializes "uninit".

So if I had a proper C++11 compiler, I could just delete
the existing constructors, and change the object definitions
to the new foo[N]{}; syntax.

What version of Visual C++ fully supports C++11?
What version of gcc fully supports C++11?

Regards.

Noob

unread,
Jun 16, 2015, 4:30:09 PM6/16/15
to
On 16/06/2015 22:16, Noob wrote:

> What version of Visual C++ fully supports C++11?

Looking bleak.
http://blogs.msdn.com/b/vcblog/archive/2014/11/17/10573602.aspx
https://blogs.msdn.com/b/vcblog/archive/2014/08/19/the-future-of-non-static-data-member-initialization.aspx

[1] NSDMIs and initializer lists were previously listed as Yes, but have been downgraded to Partial. After users encountered silent bad codegen when using braced-init-lists in NSDMIs and mem-initializer-lists, the compiler team blocked these broken scenarios with a compiler error C2797. This VCBlog post published in August has more info, and this is planned to be completely fixed in 2015 RTM.

> What version of gcc fully supports C++11?

https://gcc.gnu.org/projects/cxx0x.html
Non-static data member initializers supported since gcc 4.7

Regards.

Richard

unread,
Jun 16, 2015, 5:02:22 PM6/16/15
to
[Please do not mail me a copy of your followup]

Victor Bazarov <v.ba...@comcast.invalid> spake the secret code
<mlprkd$fc$1...@dont-email.me> thusly:

>On 6/16/2015 2:47 PM, Noob wrote:
>>[..]
>> What is the difference between new foo; and new foo{}; ?
>
>'new foo' default-initializes the object, 'new foo{}' performs the so
>called direct-initialization. They differ a bit.

I think they only differ when you actually supply values and not when
the list is empty when we're talking about classes.

I'm going from 8.5 Initializers in the standard, which says this about
direct initialization:

"The initialization that occurs in the forms

T x(a);
T x{a};

as well as in new expressions (5.3.4), static_cast expressions
(5.2.9), functional notation type conversions (5.2.3), and base
member initializers (12.6.2) is called direct-initialization."

I interpret this to mean that the 'a' argument is important here.

Earlier it is stated that X a() is value initialization.

>The one without the
>braces looks for a c-tor that can be called without the arguments, and
>if found, calls it. If none exist, it leaves the object uninitialized!

Not quite. 8.5 paragraph 12 says

"If no initializer is specified for an object, the object is
default-initialized."

Default initialization is specified as:

"To default-initialize an object of type T means:
- if T is a class type, the default constructor for T is called (and
the initialization is ill-formed if T has no default constructor or
overload resolution results in an ambiguity or in a function that is
deleted or is inaccessible from the context of the initialization);
- if T is an array type, each element is default-initialized;
- otherwise, no initialization is performed."

I interpret this to mean that the program is ill-formed if the default
constructor is unavailable for whatever reason. Generally, ill-formed
to a compiler means an error.

So when is the "no initialization performed"? If T is anything other
than a class, i.e. a scalar type such as int, pointer, double, float,
etc.

Do you interpret this differently? I am not claiming expertise in the
standard, simply interpreting it as I read it.

>IOW, 'new foo' ignores the individuals member initializers while 'new
>foo{}' uses those.

I don't think this is quite right about 'new foo' as per above.

Victor Bazarov

unread,
Jun 16, 2015, 5:06:19 PM6/16/15
to
You're likely right, and I wasn't reading the Standard carefully. I am
guessing it mostly differs for the members that *don't have* an
initializer specified for them.

Richard

unread,
Jun 16, 2015, 5:13:59 PM6/16/15
to
[Please do not mail me a copy of your followup]

Noob <ro...@127.0.0.1> spake the secret code
<mlq0tq$lrt$1...@dont-email.me> thusly:

>On 16/06/2015 22:16, Noob wrote:
>
>> What version of Visual C++ fully supports C++11?
>
>Looking bleak.

Not really. Most programmers are not going to need every single C++11
feature in the core language, never mind all the features in the
library.

>to be completely fixed in 2015 RTM.

...which is about to drop any day now.

Richard

unread,
Jun 18, 2015, 12:19:38 AM6/18/15
to
[Please do not mail me a copy of your followup]

Victor Bazarov <v.ba...@comcast.invalid> spake the secret code
<mlq31c$tsj$1...@dont-email.me> thusly:

>You're likely right, and I wasn't reading the Standard carefully. I am
>guessing it mostly differs for the members that *don't have* an
>initializer specified for them.

Yeah, if you don't specify an initializer for a member of a class,
then it is default initialized. On the github assimp project someone
pointed out to me the difference between default initialization and
value initialization:

class A {
public:
A() {}
int f[10];
};

A g;

Here g is default initialized and A::A() is called.
Member f is not mentioned in any initializer list for A::A() and
therefore is also default initialized.
Default initialization of an array means that each element is default
initialized.
Default initialization of an int does nothing special. The int will
have some storage, so its contents are undefined.

However, if we write:

class A {
public:
A() : f() {}
int f[10];
};

A g;

Then everything is as before, but f is now value initialized and allt
he ints in f will be initialized to zero.

Lőrinczy Zsigmond

unread,
Jun 18, 2015, 5:50:11 AM6/18/15
to
On 2015-06-12 22:54, Noob wrote:

> Will this work as expected?
>
> Regards.

Yes; also you can complicate it a little:

if (development) memset (*this, 0xff, sizeof *this);
else memset (*this, 0, sizeof *this);

Noob

unread,
Jun 18, 2015, 5:57:26 AM6/18/15
to
On 18/06/2015 11:48, Lőrinczy Zsigmond wrote:

> also you can complicate it a little:
>
> if (development) memset (*this, 0xff, sizeof *this);
> else memset (*this, 0, sizeof *this);

If the code depends on all fields being 0, I don't see how
setting all bytes to 0xff will help ;-)

Regards.

Lőrinczy Zsigmond

unread,
Jun 18, 2015, 6:50:50 AM6/18/15
to
> If the code depends on all fields being 0, I don't see how
> setting all bytes to 0xff will help ;-)

It helps finding the un-initialized fields.
That's why I added the "development" as the opposite of "production"

Paavo Helde

unread,
Jun 18, 2015, 10:50:27 AM6/18/15
to
=?UTF-8?B?TMWRcmluY3p5IFpzaWdtb25k?= <zs...@nospam.for.me> wrote in
news:mlu7pm$m5a$1...@speranza.aioe.org:

>> If the code depends on all fields being 0, I don't see how
>> setting all bytes to 0xff will help ;-)
>
> It helps finding the un-initialized fields.

No, it doesn't. Inside the constructor body most fields should be already
initialized so this is just overwriting them with garbage.

What one could do is to add custom operator new to the class and use the
memset() command there. In the (end of the) constructor one could then use
memchr(...,0xff,...) for finding any uninitialized fields (assuming no byte
should actually be initialized to 0xff).

Cheers
Paavo

Lőrinczy Zsigmond

unread,
Jun 18, 2015, 11:16:37 AM6/18/15
to
On 2015-06-18 16:50, Paavo Helde wrote:

> No, it doesn't. Inside the constructor body most fields should be already
> initialized so this is just overwriting them with garbage.

Sounds bad to me: 'most of the fields'...
If not 'all of them', then it means I cannot rely on this

PS: Yossi Kreinin explained this clearer than I ever could:
http://yosefk.com/c++fqa/ctors.html#fqa-10.6

Victor Bazarov

unread,
Jun 18, 2015, 11:21:28 AM6/18/15
to
On 6/18/2015 11:15 AM, Lőrinczy Zsigmond wrote:
> On 2015-06-18 16:50, Paavo Helde wrote:
>
>> No, it doesn't. Inside the constructor body most fields should be already
>> initialized so this is just overwriting them with garbage.
>
> Sounds bad to me: 'most of the fields'...
> If not 'all of them', then it means I cannot rely on this

If the class is a pseudo-POD (all members are themselves PODs, and no
virtual functions), then it's "all the fields", but the problem of
stomping all over the already initialized ones still remains, of course.

>
> PS: Yossi Kreinin explained this clearer than I ever could:
> http://yosefk.com/c++fqa/ctors.html#fqa-10.6

Lőrinczy Zsigmond

unread,
Jun 18, 2015, 11:54:34 AM6/18/15
to
> If the class is a pseudo-POD (all members are themselves PODs, and no
> virtual functions), then it's "all the fields"

Does it imply that OP's problem doesn't exist at all?

"Turns out the program defines several large classes (~50 fields,
mostly int's or int arrays, and a few pointers). The constructor
is supposed to set everything to 0s and NULLs, but it misses a
few fields, and the program blows up when it uses one of these
uninitialized fields."

Victor Bazarov

unread,
Jun 18, 2015, 12:10:06 PM6/18/15
to
The problem does exist, and, as usual is of their own making. Built-in
types, pointers included, when default-initialized (as opposed to
value-initialized), are left untouched. Memory is allocated for them,
but the contents of the memory is left unchanged. That can be A BAD
THING(tm) if you rely on the values to be specific, like 'NULL' for
pointers or 0s for counters.

The default-initialization (leaving the memory unchanged) is an
optimization step. If you don't care what the value was before changing
it in the course of your calculations, then why bother initializing it
at all? Only initialize when you need particular values to actually be
there. And if you didn't put any value in it, you can't rely on that
value. Plain and simple.

Paavo Helde

unread,
Jun 18, 2015, 2:48:55 PM6/18/15
to
Lőrinczy Zsigmond <zs...@nospam.for.me> wrote in
news:mlunc8$u2h$1...@speranza.aioe.org:
Do not take this anti-FAQ too seriously. In proper C++ code most fields
should still be initialized by initialization lists. There are some
exceptions where this is too cumbersome. Also in C++03 arrays could not be
initialized in initializer lists, but C++11 seems to have solved that.

Cheers
Paavo

Lőrinczy Zsigmond

unread,
Jun 18, 2015, 3:15:53 PM6/18/15
to
On 2015.06.18. 20:48, Paavo Helde wrote:

> Do not take this anti-FAQ too seriously. In proper C++ code most fields
> should still be initialized by initialization lists. There are some
> exceptions where this is too cumbersome. Also in C++03 arrays could not be
> initialized in initializer lists, but C++11 seems to have solved that.

Sadly, what Yossi wrote is completely matches my own experiences:
in the initializer-list you can only use a crippled-down version
of the language;
in the body of the constructor you can use the actual language.

(PS: C++ is more than thirty years old, at this age it's a bit strange
that we keep saying 'well the language is still not mature yet,
but the next version of the standard will bring big changes')

Paavo Helde

unread,
Jun 18, 2015, 3:44:37 PM6/18/15
to
=?UTF-8?B?TMWRcmluY3p5IFpzaWdtb25k?= <nos...@for.me> wrote in
news:mlv5cn$2a1$1...@speranza.aioe.org:

> On 2015.06.18. 20:48, Paavo Helde wrote:
>
>> Do not take this anti-FAQ too seriously. In proper C++ code most
>> fields should still be initialized by initialization lists. There are
>> some exceptions where this is too cumbersome. Also in C++03 arrays
>> could not be initialized in initializer lists, but C++11 seems to
>> have solved that.
>
> Sadly, what Yossi wrote is completely matches my own experiences:
> in the initializer-list you can only use a crippled-down version
> of the language;
> in the body of the constructor you can use the actual language.

I get a feeling that you might prefer to do things in overly complicated
ways. This does not help with long-term codebase maintenance.

>
> (PS: C++ is more than thirty years old, at this age it's a bit strange
> that we keep saying 'well the language is still not mature yet,
> but the next version of the standard will bring big changes')

Who are the 'we' who do keep saying that? The C++11 version is 4 years in
the past and there are no big changes planned for next releases.

Anyway, it would be a sign of decline if a language would not keep pace
with the new developments in hardware and computer science. It is a good
thing threading was not standardized before one got full taste of
multicore hardware, and it is a good thing that no GUI framework has been
standardized up to now.

Cheers
Paavo


Richard

unread,
Jun 18, 2015, 4:13:24 PM6/18/15
to
[Please do not mail me a copy of your followup]

Paavo Helde <myfir...@osa.pri.ee> spake the secret code
<XnsA4BDDDDE57007m...@216.166.105.131> thusly:

>exceptions where this is too cumbersome. Also in C++03 arrays could not be
>initialized in initializer lists, but C++11 seems to have solved that.

C++03 introduced value initialization so you can initialize arrays to
zero this way:

class C {
public:
C() : a() {}

private:
int a[10];
};

C++98 does not have it.

Richard

unread,
Jun 18, 2015, 4:15:18 PM6/18/15
to
[Please do not mail me a copy of your followup]

(Richard) legaliz...@mail.xmission.com spake the secret code
<mlv8oq$dm4$1...@news.xmission.com> thusly:

>C++03 introduced value initialization [...]

As I don't have a C++03 standard to consult, I'm going by:
<http://en.cppreference.com/w/cpp/language/value_initialization>

woodb...@gmail.com

unread,
Jun 18, 2015, 10:03:00 PM6/18/15
to
On Thursday, June 18, 2015 at 2:44:37 PM UTC-5, Paavo Helde wrote:
> =?UTF-8?B?TMWRcmluY3p5IFpzaWdtb25k?= <nos...@for.me> wrote in
> news:mlv5cn$2a1$1...@speranza.aioe.org:
>
> > On 2015.06.18. 20:48, Paavo Helde wrote:
> >
> >> Do not take this anti-FAQ too seriously. In proper C++ code most
> >> fields should still be initialized by initialization lists. There are
> >> some exceptions where this is too cumbersome. Also in C++03 arrays
> >> could not be initialized in initializer lists, but C++11 seems to
> >> have solved that.
> >
> > Sadly, what Yossi wrote is completely matches my own experiences:
> > in the initializer-list you can only use a crippled-down version
> > of the language;
> > in the body of the constructor you can use the actual language.
>
> I get a feeling that you might prefer to do things in overly complicated
> ways. This does not help with long-term codebase maintenance.
>
> >
> > (PS: C++ is more than thirty years old, at this age it's a bit strange
> > that we keep saying 'well the language is still not mature yet,
> > but the next version of the standard will bring big changes')
>

Better late than never.

Brian
Ebenezer Enterprises - In G-d we trust.
http://webEbenezer.net


> Who are the 'we' who do keep saying that? The C++11 version is 4 years in
> the past and there are no big changes planned for next releases.

support for modules is a big thing.



Lőrinczy Zsigmond

unread,
Jun 19, 2015, 5:28:45 AM6/19/15
to
>> "Turns out the program defines several large classes (~50 fields,
>> mostly int's or int arrays, and a few pointers). The constructor
>> is supposed to set everything to 0s and NULLs, but it misses a
>> few fields, and the program blows up when it uses one of these
>> uninitialized fields."

> The problem does exist, and, as usual is of their own making. Built-in
> types, pointers included, when default-initialized (as opposed to
> value-initialized), are left untouched. Memory is allocated for them,
> but the contents of the memory is left unchanged. That can be A BAD
> THING(tm) if you rely on the values to be specific, like 'NULL' for
> pointers or 0s for counters.

So we are back to square one:

1. The fields are initialised, but initialisation actually means:
they contain memory-garbage.
2. So it's a good idea to 'memset' it with zero.

Victor Bazarov

unread,
Jun 19, 2015, 7:40:15 AM6/19/15
to
A better idea would be to use one's brain instead of a bigger hammer.
If you need the memory to contain a specific value, be it zero or
nullptr (which is *not necessarily* "all bits zero", BTW) or something
else, set the member to that value. Explicitly.

Richard

unread,
Jun 19, 2015, 12:25:58 PM6/19/15
to
[Please do not mail me a copy of your followup]

=?windows-1250?Q?L=F5rinczy_Zsigmond?= <zs...@nospam.for.me> spake the secret code
<mm0nbv$8nr$1...@speranza.aioe.org> thusly:

>So we are back to square one:
>
>1. The fields are initialised, but initialisation actually means:
> they contain memory-garbage.

No. Because they are left out of the initializer list they are *not*
initialized.

>2. So it's a good idea to 'memset' it with zero.

No. You should initialize them in the initializer list.

Scott Lurndal

unread,
Jun 19, 2015, 12:37:13 PM6/19/15
to
legaliz...@mail.xmission.com (Richard) writes:
>[Please do not mail me a copy of your followup]
>
>=?windows-1250?Q?L=F5rinczy_Zsigmond?= <zs...@nospam.for.me> spake the secret code
><mm0nbv$8nr$1...@speranza.aioe.org> thusly:
>
>>So we are back to square one:
>>
>>1. The fields are initialised, but initialisation actually means:
>> they contain memory-garbage.
>
>No. Because they are left out of the initializer list they are *not*
>initialized.

To be pedantic, that differs based on the scope of the
object being initialized. For a file-scope (static)
object, they _will_ be initialized on any modern implementation.

Personally, I'll either initialize the fields in the constructor
or have a 'new' operator overload that zeros the allocated region.

Not a big fan of using initializer lists for POD MOS.

Richard

unread,
Jun 19, 2015, 1:15:55 PM6/19/15
to
[Please do not mail me a copy of your followup]

sl...@pacbell.net spake the secret code
<PyXgx.102817$gc3...@fx05.iad> thusly:

>legaliz...@mail.xmission.com (Richard) writes:
>>[Please do not mail me a copy of your followup]
>>
>>=?windows-1250?Q?L=F5rinczy_Zsigmond?= <zs...@nospam.for.me> spake the
>secret code
>><mm0nbv$8nr$1...@speranza.aioe.org> thusly:
>>
>>>So we are back to square one:
>>>
>>>1. The fields are initialised, but initialisation actually means:
>>> they contain memory-garbage.
>>
>>No. Because they are left out of the initializer list they are *not*
>>initialized.
>
>To be pedantic, that differs based on the scope of the
>object being initialized. For a file-scope (static)
>object, they _will_ be initialized on any modern implementation.

Where is this guaranteed in the standard?

If it isn't guaranteed, then it they are free to change it and
compilers are changing a lot these days.

Code should be written to be correct by design, not correct by accident.

Scott Lurndal

unread,
Jun 19, 2015, 2:06:01 PM6/19/15
to
legaliz...@mail.xmission.com (Richard) writes:
>[Please do not mail me a copy of your followup]

>>To be pedantic, that differs based on the scope of the
>>object being initialized. For a file-scope (static)
>>object, they _will_ be initialized on any modern implementation.
>
>Where is this guaranteed in the standard?
>
>If it isn't guaranteed, then it they are free to change it and
>compilers are changing a lot these days.

If it were changed, it would break 40 years of code. Not a good idea.

Richard

unread,
Jun 19, 2015, 2:09:16 PM6/19/15
to
[Please do not mail me a copy of your followup]

(Richard) legaliz...@mail.xmission.com spake the secret code
<mm1io2$su1$1...@news.xmission.com> thusly:

>[Please do not mail me a copy of your followup]
>
>sl...@pacbell.net spake the secret code
><PyXgx.102817$gc3...@fx05.iad> thusly:
>
>>legaliz...@mail.xmission.com (Richard) writes:
>>>[Please do not mail me a copy of your followup]
>>>
>>>=?windows-1250?Q?L=F5rinczy_Zsigmond?= <zs...@nospam.for.me> spake the
>>secret code
>>><mm0nbv$8nr$1...@speranza.aioe.org> thusly:
>>>
>>>>So we are back to square one:
>>>>
>>>>1. The fields are initialised, but initialisation actually means:
>>>> they contain memory-garbage.
>>>
>>>No. Because they are left out of the initializer list they are *not*
>>>initialized.
>>
>>To be pedantic, that differs based on the scope of the
>>object being initialized. For a file-scope (static)
>>object, they _will_ be initialized on any modern implementation.
>
>Where is this guaranteed in the standard?

Answering my own question: 8.5 Initializers, paragraph 10:

"Note: Every object of static storage duration is zero-initialized at
program startup before any other initialization takes place."

Noob

unread,
Jun 19, 2015, 2:27:36 PM6/19/15
to
On 18/06/2015 21:44, Paavo Helde wrote:

> Who are the 'we' who do keep saying that? The C++11 version is 4 years in
> the past and there are no big changes planned for next releases.

AFAICT, neither gcc nor VS fully support C++11 even today.

Wouter van Ooijen

unread,
Jun 19, 2015, 3:26:12 PM6/19/15
to
Noob schreef op 19-Jun-15 om 8:27 PM:
What are you missing in GCC?

The only thing I could find at https://gcc.gnu.org/projects/cxx0x.html
(C++ 11) is "Minimal support for garbage collection and
reachability-based leak detection", but the linked description doesn't
make me feel that I am missing a compiler feature, it seems to be an
issue about what constitutes a valid C++ program.

https://gcc.gnu.org/projects/cxx1y.html seems to claim full C++ 14 support.

Wouter van Ooijen

Noob

unread,
Jun 20, 2015, 4:36:18 AM6/20/15
to
You're right. My comment was based on obsolete info.

gcc 4.8 docs stated "Support for C++11 is still experimental, and may
change in incompatible ways in future releases." but that qualification
was removed in gcc 4.9 docs. So I should upgrade my tool chain.

But the problem is that this project's Windows binaries are supposed
to be generated with VS, which is lagging in C++11 support.
(Perhaps Microsoft is too busy pushing C#)

Regards.

JiiPee

unread,
Jun 20, 2015, 7:00:02 AM6/20/15
to
On 13/06/2015 00:56, Victor Bazarov wrote:
> On 6/12/2015 7:39 PM, Stefan Ram wrote:
>> Ian Collins <ian-...@hotmail.com> writes:
>>> Richard wrote:
>>>> shell 161> g++ -Weffc++ /tmp/a.cpp
>>> A gcc option that breaks google :)
>>> Your search - -Weffc++ - did not match any documents.
>>
>> It only »breaks« the expectations of Google users who did
>> not study the Google operators manual before using the Google
>> »-« operator in their Google search specifications.
>
> Pfft! Real programmers never read manuals! ;-)
>
> V

More commonly: Men do not read manuals when buying something and start
using it

Richard

unread,
Jun 22, 2015, 1:33:42 PM6/22/15
to
[Please do not mail me a copy of your followup]

Noob <ro...@127.0.0.1> spake the secret code
<mm1mrv$hho$1...@dont-email.me> thusly:
C++11 support in VS is quite good from my perspective.
<https://utahcpp.wordpress.com/2015/06/22/c111417-features-in-visual-studio-2015/>

Microsoft has been improving their compiler rapidly in recent years.
If you haven't looked at it in a while, you're missing a lot.

JiiPee

unread,
Jun 22, 2015, 4:35:01 PM6/22/15
to
On 18/06/2015 17:09, Victor Bazarov wrote:
> On 6/18/2015 11:53 AM, Lőrinczy Zsigmond wrote:
>>> If the class is a pseudo-POD (all members are themselves PODs, and no
>>> virtual functions), then it's "all the fields"
>>
>> Does it imply that OP's problem doesn't exist at all?
>>
>> "Turns out the program defines several large classes (~50 fields,
>> mostly int's or int arrays, and a few pointers). The constructor
>> is supposed to set everything to 0s and NULLs, but it misses a
>> few fields, and the program blows up when it uses one of these
>> uninitialized fields."
>
> The problem does exist, and, as usual is of their own making. Built-in
> types, pointers included, when default-initialized (as opposed to
> value-initialized), are left untouched. Memory is allocated for them,
> but the contents of the memory is left unchanged.

If I remember correctly globals are initialized by their "zero values",
like
int a;
if global would be initialized to zero. Right?
local variables are like you said...

>
> The default-initialization (leaving the memory unchanged) is an
> optimization step. If you don't care what the value was before
> changing it in the course of your calculations, then why bother
> initializing it at all? Only initialize when you need particular
> values to actually be there.

so, would you initialize:
int* p = nullptr;
or just :
int* p;
? I think it would be safer to put nullptr so that other code knows its
not pointing to anywhere.

alf.p.s...@gmail.com

unread,
Jun 22, 2015, 8:03:07 PM6/22/15
to
Instead of (as an example) this:

class Foo
{
private:
int golgoroth_;
float fiskepudding_;
double color_;
public:
Foo( char const* ): golgoroth_( 1 ), color_( 2.718128 ) {}
Foo( float ): golgoroth_( 1 ), fiskepudding_( 0 ) {}
};

auto main() -> int {}

you can do this, which automates & guarantees the zeroing:

template< class Base >
struct Initialized_POD
: Base
{
Initialized_POD(): Base() {} // Value-init -> zero-init
};

struct Foo_state
{
int golgoroth_;
float fiskepudding_;
double color_;
};

class Foo
: private Initialized_POD< Foo_state >
{
public:
Foo( char const* ) { golgoroth_ = 1; color_ = 2.718128; }
Foo( float ) { golgoroth_ = 1; }
};

auto main() -> int {}

It's not universally applicable, rather the opposite, but I suspect it might be Just The Thing(tm) for your concrete problem.

It's more safe than the memset approach -- maintainers can't forget to zero things, and there's no problem with later introduction of virtual functions -- and it's also less code in general, even though it might look somewhat verbose in the short example above. Compiled with optimization it should be just as efficient as memset. I.e., no known big problems, some nice advantages. :)

Cheers & hth.,

- Alf

alf.p.s...@gmail.com

unread,
Jun 22, 2015, 8:48:01 PM6/22/15
to
On Tuesday, June 23, 2015 at 2:03:07 AM UTC+2, alf.p.s...@gmail.com wrote:
>
> you can do this, which automates & guarantees the zeroing:
>
> template< class Base >
> struct Initialized_POD
> : Base
> {
> Initialized_POD(): Base() {} // Value-init -> zero-init
> };
>

Looking at it again, a better name might be just `Zeroed`.

Richard

unread,
Jun 22, 2015, 9:24:23 PM6/22/15
to
[Please do not mail me a copy of your followup]

alf.p.s...@gmail.com spake the secret code
<7778733f-4744-43c6...@googlegroups.com> thusly:
That's a nice little snippet, a great contribution to this thread.

David Brown

unread,
Jun 23, 2015, 2:17:20 AM6/23/15
to
No, it is (normally) better not to put a fake value in initialisation.
Putting a fake value might mislead people into thinking it is a real
value, and it stops the compiler being able to warn you if you use it
before putting in the real value (compilers can warn about the use of
uninitialised variables in most cases).

So if you don't have anything sensible to put in your variable, don't
put anything in it (or don't declare it at all until you need it).
Message has been deleted

Noob

unread,
Jun 23, 2015, 3:12:40 PM6/23/15
to
On 22/06/2015 19:33, Richard wrote:

> [Please do not mail me a copy of your followup]

(I find this foreword annoying.)

> C++11 support in VS is quite good from my perspective.
> <https://utahcpp.wordpress.com/2015/06/22/c111417-features-in-visual-studio-2015/>

VS2015 is unreleased software. It doesn't support anything (yet).

> Microsoft has been improving their compiler rapidly in recent years.
> If you haven't looked at it in a while, you're missing a lot.

Well, I have gcc and clang, I don't need VS.

Regards.

Vir Campestris

unread,
Jun 23, 2015, 4:27:34 PM6/23/15
to
On 23/06/2015 20:12, Noob wrote:
> Well, I have gcc and clang, I don't need VS.

You haven't tried VS have you?

gcc and clang are compilers. They may even be better compilers than the
one in VS as they fight each other for the same market.

VS is an IDE. I can't find anything nearly as good on Linux. I'm using
Eclipse, but it's clunky and unreliable in comparison.

Andy

Richard

unread,
Jun 23, 2015, 4:29:23 PM6/23/15
to
[Please do not mail me a copy of your followup]

Noob <ro...@127.0.0.1> spake the secret code
<mmcb05$s58$1...@dont-email.me> thusly:

>On 22/06/2015 19:33, Richard wrote:
>
>(I find this foreword annoying.)

Well, at least you're consistent in being a complainer.

>> C++11 support in VS is quite good from my perspective.
>>
><https://utahcpp.wordpress.com/2015/06/22/c111417-features-in-visual-studio-2015/>
>
>VS2015 is unreleased software. It doesn't support anything (yet).

VS2015 community edition release candidate is available now.
<https://www.visualstudio.com/>

The community technology preview releases have been available for many
months. While those releases were not advertised as being "ready for
prime time", it would allow you to evaluate C++11/14/17 conformance on
your code base.

When people talk about VS not "fully supporting C++xx", this is a
statement that is simultaneously true and not very useful. The reason
it isn't very useful is because the parts that VS doesn't yet support
may not be present in your code base and therefore, the lack of support
may be completely irrelevant. Lots of commercial code bases aren't
even modernized to use C++11 features yet, so harping on the lack of
something like C++14 support for say SFINAE-friendly result_of from
proposal N3462 is probably not that useful.

Unless, of course, you really depend on that feature and then it's
important. The authors of that proposal are Eric Niebler, Daniel
Walker and Joel de Guzman. I've met Eric in person and have had many
email discussions with Joel. I am not familiar with Daniel Walker,
but judging by his company on this proposal, I'm sure I'd respect his
thoughts on these matters as I do Eric and Joel. Eric and Joel are heavy
contributors to libraries in Boost. The life of a library writer is much,
much different form the life of a library consumer -- in other words
an application developer. The point is that N3462 may or may not be
important to your code base. It certainly is irrelevant if you, and
none of the header-only libraries you use, depend on std::result_of.

The lack of support in VS2013 for constexpr could be considerably more
annoying, but we've been doing many of these sorts of things in
clumsier ways all along. Many of the features in C++11 are focused on
making things easier in the language, as opposed to making impossible
things possible. However, even in the case of constexpr things aren't
as bleak as they might appear at first if your investigation is simply
"bah! It doesn't support constexpr, they suck!" Let's look at the
timeline:

2013-06 Visual Studio 2013 released, no constexpr support
2013-11 VS Nov 2013 CTP0, partial constexpr support
2014-06 VS14 CTP1, partial constexpr support
2014-08 VS14 CTP3, partial constexpr support
2014-11 VS 2015 preview, partial constexpr support
2015-04 VS 2015 RC, constexpr almost complete modulo compiler bugs
2015-06-02 constexpr complete for VS 2015 RTM[*]
[*] <http://bit.ly/1LzK1it>
2015-06-23 VS 2015 RC available for free

For the size of the team at Microsoft -- I've met a few of them over
the years as an MVP -- I'd say they're doing a really good job of
getting the standard into the hands of Windows developers while
maintaining the quality of implementation.

>> Microsoft has been improving their compiler rapidly in recent years.
>> If you haven't looked at it in a while, you're missing a lot.
>
>Well, I have gcc and clang, I don't need VS.

Elsewhere in this thread you wrote:

> But the problem is that this project's Windows binaries are supposed
> to be generated with VS, which is lagging in C++11 support.

...which implies that you *do* need it.

> (Perhaps Microsoft is too busy pushing C#)

...and this implies that you don't know what you're talking about, but
are mostly interested in complaining about Microsoft.

Ian Collins

unread,
Jun 23, 2015, 4:30:18 PM6/23/15
to
If you like VS, try NetBeans. The two are uncannily similar in many ways.

--
Ian Collins

Scott Lurndal

unread,
Jun 23, 2015, 4:49:40 PM6/23/15
to
Who needs an IDE? I cannot stand to use any of them.

Richard

unread,
Jun 23, 2015, 5:26:12 PM6/23/15
to
[Please do not mail me a copy of your followup]

Vir Campestris <vir.cam...@invalid.invalid> spake the secret code
<JbSdnWA9G5G1XBTI...@brightview.co.uk> thusly:

>VS is an IDE. I can't find anything nearly as good on Linux.

Try CLion. It's the first viable competitor I've seen to VS so far.

Richard

unread,
Jun 23, 2015, 5:28:44 PM6/23/15
to
[Please do not mail me a copy of your followup]

sl...@pacbell.net spake the secret code
<uDjix.87350$sD1....@fx25.iad> thusly:

>Who needs an IDE? I cannot stand to use any of them.

I used to have that attitude in the mid/late 90s when I switched from
working at a unix shop to working at a Windows shop. Initially I kept
my emacs on Windows and worked primarily in emacs for editing and only
used VS for compiling. Over time, I learned to use the VS IDE and
found myself being more productive at navigating through and
manipulating my code. The only thing that's come close to being that
productive is CLion and it barely just came out.

Noob

unread,
Jun 23, 2015, 6:02:30 PM6/23/15
to
On 23/06/2015 22:29, Richard wrote:

> [Please do not mail me a copy of your followup]

Well, I may just have to start mailing you a copy of all my
Usenet followups.

> VS2015 community edition release candidate is available now.
> <https://www.visualstudio.com/>
>
> The community technology preview releases have been available for many
> months. While those releases were not advertised as being "ready for
> prime time", it would allow you to evaluate C++11/14/17 conformance on
> your code base.

AFAICT, VS2013 was supposed to support C++11 NSDMI (a feature which
YOU suggested I use). And that feature had to be removed because the
implementation didn't get it right. Are you sure VS2015 gets it right?

> For the size of the team at Microsoft -- I've met a few of them over
> the years as an MVP -- I'd say they're doing a really good job of
> getting the standard into the hands of Windows developers while
> maintaining the quality of implementation.

suum cuique.

> Elsewhere in this thread you wrote:
>
>> But the problem is that this project's Windows binaries are supposed
>> to be generated with VS, which is lagging in C++11 support.
>
> ...which implies that you *do* need it.

To be precise: I'm building the Linux version, and another fellow
builds the Windows version (using VS2012 IIUC). I just have to avoid
using syntax VS2012 doesn't approve.

>> (Perhaps Microsoft is too busy pushing C#)
>
> ...and this implies that you don't know what you're talking about, but
> are mostly interested in complaining about Microsoft.

One shouldn't let facts get in the way of a proper trolling opportunity.
How's C11 support in VS coming along, by the way? :-p

Regards.

David Brown

unread,
Jun 24, 2015, 3:30:20 AM6/24/15
to
On 23/06/15 23:26, Richard wrote:
> [Please do not mail me a copy of your followup]
>
> Vir Campestris <vir.cam...@invalid.invalid> spake the secret code
> <JbSdnWA9G5G1XBTI...@brightview.co.uk> thusly:
>
>> VS is an IDE. I can't find anything nearly as good on Linux.
>
> Try CLion. It's the first viable competitor I've seen to VS so far.
>

What does CLion give you that Eclipse does not? I had a little look at
their website, and it appeared to be a reasonable enough IDE - but I saw
nothing to make me think that it stood out in any way.


Scott Lurndal

unread,
Jun 24, 2015, 9:06:36 AM6/24/15
to
legaliz...@mail.xmission.com (Richard) writes:
>[Please do not mail me a copy of your followup]
>
>sl...@pacbell.net spake the secret code
><uDjix.87350$sD1....@fx25.iad> thusly:
>
>>Who needs an IDE? I cannot stand to use any of them.
>
>I used to have that attitude in the mid/late 90s when I switched from
>working at a unix shop to working at a Windows shop. Initially I kept
>my emacs on Windows and worked primarily in emacs for editing and only
>used VS for compiling. Over time, I learned to use the VS IDE and
>found myself being more productive at navigating through and
>manipulating my code. The only thing that's come close to being that
>productive is CLion and it barely just came out.

I cannot argue with your experience. I can, however, rejoice
that I need never work in a Windows shop.

Richard

unread,
Jun 24, 2015, 2:37:44 PM6/24/15
to
[Please do not mail me a copy of your followup]

David Brown <david...@hesbynett.no> spake the secret code
<mmdm79$ram$1...@dont-email.me> thusly:

>What does CLion give you that Eclipse does not? I had a little look at
>their website, and it appeared to be a reasonable enough IDE - but I saw
>nothing to make me think that it stood out in any way.

I've not attempted Eclipse for C++ development, but I did give it a try
for about a month doing Java development. I found it very frustrating.
Every member of my team that was using eclipse was using a slightly
different bundle of eclipse. None of the regular eclipse users could
explain to me how to fix any of the problems I was encountering, none
of them could explain to me how the IDE worked from a conceptual level,
and if they did have solutions to a problem, each person had a
different solution because they were all using a different "eclipse".
Most of the time their explanation (when they had one) went like this:
"I don't know why it does that, but here's the hammer I use to beat it
back down". Of course, their hammers didn't work on the bundle of
eclipse that I had downloaded.

After about a month of frustration, I decided to try out IntelliJ.
WOW. The difference was night and day. Suddenly, I didn't have to
fight with the IDE anymore, I could just work on my code and get things
done. Yes, the key bindings were different from what I was used to
(Visual Studio), but after learning the default key bindings I found I
was just as productive on Java code in IntelliJ as I was in C++ with
Visual Studio. Even better, IntelliJ had very good refactoring, code
navigation support and "quick fixes" for things that it noticed about
my code using static analysis. About the only thing I missed from VS
was its window docking system. The one in IntelliJ is not very
intuitive for me and isn't as easy to configure as Visual Studio.

Why am I mentioning all this? Because IntelliJ is the IDE foundation
on which all other IDEs from JetBrains are built. CLion is an
IntelliJ-based IDE. The default keyboard shortcut scheme is the same,
the docking window system is the same, the preferences and settings
system is the same, etc. CLion provides quite a good bit of
refactoring support and the refactorings are well implemented and
reliable. They have scored the highest score on my refactoring test
suite for Rename, for instance.
<https://github.com/LegalizeAdulthood/refactor-test-suite>

I've used CLion on linux for several months before their final release
and I've continued to use it since. I mostly do my clang contributions
on linux using CLion.

About the only advantage Eclipse has over CLion is that it's free.
However, the increased productivity with CLion more than makes up for
its cost, unless you don't value your time very highly. There was a
point in my life where I had more time than money and I probably would
have chosen Eclipse myself at that point. However, now I'm in the
reverse situations: I'm more limited by time than money, so my time is
very precious to me. I wouldn't want to do any unix C++ development
work with anything but CLion at this point. Although it currently
requires CMake for its project system, they are working on supporting
other project systems (probably something Makefile based) in future
releases. The productivity gains are enough that I'd be willing to
convert my build to CMake *just* to use CLion.

Richard

unread,
Jun 24, 2015, 2:45:56 PM6/24/15
to
[Please do not mail me a copy of your followup]

Noob <ro...@127.0.0.1> spake the secret code
<mmckuq$5uk$1...@dont-email.me> thusly:

>On 23/06/2015 22:29, Richard wrote:
>
>> [Please do not mail me a copy of your followup]
>
>Well, I may just have to start mailing you a copy of all my
>Usenet followups.

My KILL file has plenty of room and so does my procmail filter.

David Brown

unread,
Jun 24, 2015, 4:57:36 PM6/24/15
to
Thanks for writing that.

I can't answer for Java - I have never worked with Java development. I
am only thinking of C and C++ here.

When I first used eclipse, a good number of years ago, I found it slow,
clunky, and hard to figure out. It has improved a great deal since then
(helped also by faster computers with more memory). There are a few
things I find painful, such as updates - but I rarely feel the need to
update it anyway.

I can't relate to the problems you have been having with Eclipse - I
simply haven't seen that kind of frustration. I find it works well for
my C and C++ work (mostly C), and I can navigate fairly quickly through
the code. I haven't had much use for refactoring, so I don't know how
Eclipse's refactoring compares to other IDEs. But it does a good job of
editing, makes good suggestions for completing identifiers, is helpful
in formatting, checks and corrects my spelling, and quickly marks
potential errors in the code. It also works well with makefiles (I
almost always work with external makefiles, not the IDE's project
manager) and interprets the error messages from the compiler. Debugging
also works well enough, connecting to my embedded systems using openocd
or other proxies and interfaces.

I also use Eclipse for Python development and LaTeX documentation. It
is important to me to be able to have multiple copies of the IDE open at
the same time, with different workspaces - Eclipse handles that without
problem.

JiiPee

unread,
Jun 24, 2015, 7:16:37 PM6/24/15
to
On 13/06/2015 10:32, Christian Gollwitzer wrote:
>
> and in C++11 it is even easier:
>
> class SomeClass {
> public:
> SomeClass() {}
> explicit SomeClass(int new_value) : value(new_value) {}
>
> private:
> int value = 5;
> };

A bit better would be :

int value{5};

?
With int it does not make difference but with an class it might.

JiiPee

unread,
Jun 24, 2015, 7:18:26 PM6/24/15
to
On 13/06/2015 18:33, Noob wrote:
>
> Your example is nice with 1 field. But the actual definition
> is more like this:
>
> class foo {
> public:
> int aa, bb, cc, ...
> int va[Na], vb[Nb], ...
> int v2a[N2a][Ma], v2b[N2b][Mb], ...
> bar *p1, baz *p2, ...
>
> foo();
> ~foo();
> 40 methods
> };
>
> Would it still look simple then?
>

40 methods in a class ? :) maybe a bit too much... there should be only
a few in a class normally?

JiiPee

unread,
Jun 24, 2015, 8:07:19 PM6/24/15
to
On 23/06/2015 07:17, David Brown wrote:
> On 22/06/15 22:34, JiiPee wrote:
>>
>> so, would you initialize:
>> int* p = nullptr;
>> or just :
>> int* p;
>> ? I think it would be safer to put nullptr so that other code knows its
>> not pointing to anywhere.
> No, it is (normally) better not to put a fake value in initialisation.
> Putting a fake value might mislead people into thinking it is a real
> value, and it stops the compiler being able to warn you if you use it
> before putting in the real value (compilers can warn about the use of
> uninitialised variables in most cases).

class Vector
{
public:
Vector() : data(nullptr) {}
void allocate(int size) { if(data==nullptr) data = new int[size];
else....}
private:
int* data;
int size=0;
};

Here, isnt it a good idea to use nullptr initialization?
Also, there is a risk that due to human errors we would have a bug such
that we do not remember to assign any valid value to this pointer. Then
it has a random address and can possible crash the program. But if you
set it to NULL then at least we can debug and find where is the problem.
if its not null we cannot even find it when debugging... could be a very
difficult to find such a bug because this pointer tell the rest of the
code: "hey, I have a valid address to use" even though it does not....

Thats why it eliminates this kind of risk, right?

JiiPee

unread,
Jun 24, 2015, 8:15:24 PM6/24/15
to
On 23/06/2015 07:17, David Brown wrote:
many functions assume that nullptr means "uninitialized" or "not set".
Thats why I think a pointer is an exeption here. yes, for an integer
what you said holds:

int a; // if no sensible value, then dont initialize
int* p = nullptr; // just make sure functions checking uninitialize
condition know that pointer is not set
Rectangle rect1; // no need to initialize necessary

pointer is a different here than others , right? so, its good to
initialize pointers to null but not initialize other type of objects/vars?

JiiPee

unread,
Jun 24, 2015, 8:16:59 PM6/24/15
to
On 23/06/2015 07:35, Stefan Ram wrote:
> JiiPee <n...@notvalid.com> writes:
>> so, would you initialize:
>> int* p = nullptr;
>> or just :
>> int* p;
>> ? I think it would be safer to put nullptr so that other code knows its
>> not pointing to anywhere.
> Show the full function and then we will see that there will
> be a natural way to rewrite the function into a form where
> every variable is initialized with a natural value if it is
> known what that function is supposed to do.
>

but what if we are talking about class members which are pointer types?
So not about functions

Ian Collins

unread,
Jun 24, 2015, 8:19:55 PM6/24/15
to
If the class manages whatever the pointer will be assigned to, then yes
it should be initialised otherwise the class destructor may try and
delete garbage.

--
Ian Collins

JiiPee

unread,
Jun 24, 2015, 8:23:54 PM6/24/15
to
On 23/06/2015 01:02, alf.p.s...@gmail.com wrote:
> auto main() -> int {}

heh, nice little trick I did not think before.... :) this works! new
form of main

Richard

unread,
Jun 24, 2015, 8:49:53 PM6/24/15
to
[Please do not mail me a copy of your followup]

n...@notvalid.com spake the secret code
<JCHix.998833$qW.3...@fx20.am4> thusly:

>class Vector
>{
>public:
> Vector() : data(nullptr) {}
> void allocate(int size) { if(data==nullptr) data = new int[size];
>else....}
>private:
> int* data;
> int size=0;
>};
>
>Here, isnt it a good idea to use nullptr initialization?

Sort of. It's only a good idea because you're avoiding the other
advice for writing good C++ programs:

- don't write you own "vector", use std::vector.
- don't use raw pointers, use a smart pointer like std::unique_ptr or
std::shared_ptr

In other words, this is a contrived example for the above reasons and
isn't a useful example in which to discuss what is a good idea or not.

>Also, there is a risk that due to human errors we would have a bug such
>that we do not remember to assign any valid value to this pointer.

...which is why you shouldn't use raw pointers in the first place.

>Thats why it eliminates this kind of risk, right?

Using standard containers and smart pointers is the preferred way to
avoid the problems of raw pointers.

Richard

unread,
Jun 24, 2015, 8:50:33 PM6/24/15
to
[Please do not mail me a copy of your followup]

n...@notvalid.com spake the secret code
<kKHix.987969$dj1.4...@fx03.am4> thusly:

>many functions assume that nullptr means "uninitialized" or "not set".

Again, it's better to use smart pointers instead of raw pointers and
this problem is easily avoided.

Richard

unread,
Jun 24, 2015, 8:51:19 PM6/24/15
to
[Please do not mail me a copy of your followup]

n...@notvalid.com spake the secret code
<kSHix.1247307$dT.6...@fx35.am4> thusly:
Meh. Might as well just write

int main() {}

The use of auto and -> here feels gratuitous.

JiiPee

unread,
Jun 24, 2015, 8:53:53 PM6/24/15
to
For me I would feel risky not to initialize that member.

But sure there are situations where to optimize the performance in a
function I would not initialize it especially if the function is small
and the pointer is easily seen there as a local variable.

woodb...@gmail.com

unread,
Jun 24, 2015, 10:30:21 PM6/24/15
to
On Wednesday, June 24, 2015 at 7:49:53 PM UTC-5, Richard wrote:
> [Please do not mail me a copy of your followup]
>
> n...@notvalid.com spake the secret code
> <JCHix.998833$qW.3...@fx20.am4> thusly:
>
> >class Vector
> >{
> >public:
> > Vector() : data(nullptr) {}
> > void allocate(int size) { if(data==nullptr) data = new int[size];
> >else....}
> >private:
> > int* data;
> > int size=0;
> >};
> >
> >Here, isnt it a good idea to use nullptr initialization?
>
> Sort of. It's only a good idea because you're avoiding the other
> advice for writing good C++ programs:
>
> - don't write you own "vector", use std::vector.
> - don't use raw pointers, use a smart pointer like std::unique_ptr or
> std::shared_ptr
>

I would say to use raw pointers and use unique_ptr sparingly.
I haven't found a need for shared_ptr to this day.

Brian
Ebenezer Enterprises - So far G-d has helped us.
http://webEbenezer.net


Ian Collins

unread,
Jun 24, 2015, 10:30:49 PM6/24/15
to
David Brown wrote:
>
> I can't relate to the problems you have been having with Eclipse - I
> simply haven't seen that kind of frustration. I find it works well for
> my C and C++ work (mostly C), and I can navigate fairly quickly through
> the code. I haven't had much use for refactoring, so I don't know how
> Eclipse's refactoring compares to other IDEs. But it does a good job of
> editing, makes good suggestions for completing identifiers, is helpful
> in formatting, checks and corrects my spelling, and quickly marks
> potential errors in the code. It also works well with makefiles (I
> almost always work with external makefiles, not the IDE's project
> manager) and interprets the error messages from the compiler. Debugging
> also works well enough, connecting to my embedded systems using openocd
> or other proxies and interfaces.

One benefit I find with my mix of clients and targets
(Solaris/Illumos/Linux and embedded ARM) with NetBeans is the IDE
generates and builds from makefiles. So I can build any (or all) of the
targets from the command line. This also helps when working with Visual
Studio which can use the makefiles for a makefile project. NetBeans
also supports connections to remote hosts, so I can build my
applications for all supported versions of Linux and Solaris without
having to change windows.

> I also use Eclipse for Python development and LaTeX documentation. It
> is important to me to be able to have multiple copies of the IDE open at
> the same time, with different workspaces - Eclipse handles that without
> problem.

If you prefer (as I do) to have a single instance of the IDE open with
multiple workspaces, NetBeans is a good choice. I particularly like the
ability to associate code formatting with projects - very handy if you
have clients with different coding standards!

--
Ian Collins

Richard

unread,
Jun 24, 2015, 10:40:53 PM6/24/15
to
[Please do not mail me a copy of your followup]

Ian Collins <ian-...@hotmail.com> spake the secret code
<cv17ee...@mid.individual.net> thusly:

>One benefit I find with my mix of clients and targets
>(Solaris/Illumos/Linux and embedded ARM) with NetBeans is the IDE
>generates and builds from makefiles.

CMake can target all of those as well as Xcode and Visual Studio with
a superior experience than a plain Makefile. When using a makefile
based project in VS, it doesn't know about your source files and
locating files in the solution has to be done through File / Open
instead of the solution expolorer. When I initially came from a unix
environment I thought the solution explorer was kinda dumb, but now I
have come to find that I really do use it quite a bit and it assists
me in navigating to the various source files in my project.

I don't know how well Xcode gets along with a Makefile style project.
My experience is primarily with Xcode 3 and using it's builtin project
files (which CMake can generate without any problems).

>If you prefer (as I do) to have a single instance of the IDE open with
>multiple workspaces, NetBeans is a good choice.

With VS and CLion it's one instance of the IDE per workspace. I
*think* Xcode lets you only have a single workspace in a given
instance of Xcode and I can't remember if you can have multiple
instances running or not.

David Brown

unread,
Jun 25, 2015, 3:07:44 AM6/25/15
to
On 25/06/15 02:07, JiiPee wrote:
> On 23/06/2015 07:17, David Brown wrote:
>> On 22/06/15 22:34, JiiPee wrote:
>>>
>>> so, would you initialize:
>>> int* p = nullptr;
>>> or just :
>>> int* p;
>>> ? I think it would be safer to put nullptr so that other code knows its
>>> not pointing to anywhere.
>> No, it is (normally) better not to put a fake value in initialisation.
>> Putting a fake value might mislead people into thinking it is a real
>> value, and it stops the compiler being able to warn you if you use it
>> before putting in the real value (compilers can warn about the use of
>> uninitialised variables in most cases).
>
> class Vector
> {
> public:
> Vector() : data(nullptr) {}
> void allocate(int size) { if(data==nullptr) data = new int[size];
> else....}
> private:
> int* data;
> int size=0;
> };
>
> Here, isnt it a good idea to use nullptr initialization?

Yes, but what you are doing here is not fake initialisation - you are
actively setting the value, and relying on the fact that it is set.
It's a totally different situation. We have been talking about /fake/
initialisation, where you put in an initialiser value that will never be
used.

When you have a variable of some sort, you want it to be in a valid
state before use. If you don't currently have any possible valid state
for it, and your compiler can warn of uninitialised use, then the
general rule is don't set it to anything. Otherwise, a signalling
invalid state is a better choice.

(Here "valid state" does not just mean a value that satisfies the
constraints and invariants of the class - it means holding a value that
makes sense at that stage in the code.)

> Also, there is a risk that due to human errors we would have a bug such
> that we do not remember to assign any valid value to this pointer. Then
> it has a random address and can possible crash the program. But if you
> set it to NULL then at least we can debug and find where is the problem.
> if its not null we cannot even find it when debugging... could be a very
> difficult to find such a bug because this pointer tell the rest of the
> code: "hey, I have a valid address to use" even though it does not....
>

When considering whether or not to put a fake initial value in a
variable or object, there are a few things to consider:

1. Does it help prevent bugs in the first place, or help them get
spotted at compile-time with compiler warnings?

2. Does it make the code clearer and easier to understand and maintain?

3. Does it help make run-time bugs easily detected?

4. Does it make a /noticeable/ performance difference?


Compilers are quite good at spotting the use of uninitialised variables.
They can't do that if the variable has been initialised with fake data
- so they can't tell you that you have forgotten to put in the /real/
data. Fake data hides the problem, and turns an obvious compile-time
warning into an obscure run-time effect that will be hard to find.

Clarity of code is obviously a major priority in any decision.

If the potential bug can't be found compile-time, setting the variable
to a "safe default" can make debugging harder, not easier. Of course
details are going to vary, but your aim here is to cause a hard crash
quickly rather than have something that sort-of works. Using nullptr
for pointers is often useful on PC software, because dereferencing null
pointers can give an immediate crash. But if you have a double, you
might get better effects initialising to -1.2e87 than 0.0.

And for the Vector class you gave, you /might/ want a nullptr data to
signal that allocation should be done automatically. But you might also
want to have asserts in other methods, causing hard crashes and messages
if the class is accidentally used without being properly initialised (at
least during development!).


> Thats why it eliminates this kind of risk, right?
>

You don't /eliminate/ risks, you /reduce/ them.

David Brown

unread,
Jun 25, 2015, 3:22:33 AM6/25/15
to
On 25/06/15 04:30, Ian Collins wrote:
> David Brown wrote:
>>
>> I can't relate to the problems you have been having with Eclipse - I
>> simply haven't seen that kind of frustration. I find it works well for
>> my C and C++ work (mostly C), and I can navigate fairly quickly through
>> the code. I haven't had much use for refactoring, so I don't know how
>> Eclipse's refactoring compares to other IDEs. But it does a good job of
>> editing, makes good suggestions for completing identifiers, is helpful
>> in formatting, checks and corrects my spelling, and quickly marks
>> potential errors in the code. It also works well with makefiles (I
>> almost always work with external makefiles, not the IDE's project
>> manager) and interprets the error messages from the compiler. Debugging
>> also works well enough, connecting to my embedded systems using openocd
>> or other proxies and interfaces.
>
> One benefit I find with my mix of clients and targets
> (Solaris/Illumos/Linux and embedded ARM) with NetBeans is the IDE
> generates and builds from makefiles. So I can build any (or all) of the
> targets from the command line. This also helps when working with Visual
> Studio which can use the makefiles for a makefile project. NetBeans
> also supports connections to remote hosts, so I can build my
> applications for all supported versions of Linux and Solaris without
> having to change windows.

Eclipse also creates makefiles, but I prefer to write them myself -
combined with gcc's dependency file options my makefiles automatically
deal with updating dependency files as needed. Eclipse's project
management does quite a good job, but my makefiles are better, and
noticeably faster on big projects. It also keeps my makefiles
completely independent of the IDE - sometimes I need to build from the
command line.

>
>> I also use Eclipse for Python development and LaTeX documentation. It
>> is important to me to be able to have multiple copies of the IDE open at
>> the same time, with different workspaces - Eclipse handles that without
>> problem.
>
> If you prefer (as I do) to have a single instance of the IDE open with
> multiple workspaces, NetBeans is a good choice. I particularly like the
> ability to associate code formatting with projects - very handy if you
> have clients with different coding standards!
>

Eclipse can also associate different formatting standards with different
projects.

I am not sure it makes any difference having multiple IDE instances with
different workspaces, or having one IDE instance with multiple
workspaces - the effect is much the same. (How windows users manage to
cope without virtual desktops here is beyond me. Maybe windows users
only ever work on one thing at a time?) Since I work with various
different embedded devices, it is not uncommon for me to have different
customised versions of Eclipse open at the same time - I might have a
Freescale Kinetis Eclipse open for the firmware development, and another
"plain" Eclipse open for Python code on the PC side.

I suspect that either Eclipse or NetBeans would be as suitable for much
of my work - I use Eclipse because I am used to it (partly because it is
the standard for microcontroller development tools, with Microchip and
Atmel being almost the only exceptions). I'd be happy to try out other
IDEs, such as NetBeans or CLion, if it looked like they would be
significantly better for me - but it doesn't sound like there would be
much difference.

Öö Tiib

unread,
Jun 25, 2015, 7:04:48 AM6/25/15
to
10-15 member functions in class is quite livable but 40 is
smelly (too lot of responsibilities) and should be perhaps
split up.

However things are worse in some code bases. Longest
god class I have seen was 137 000 lines of C# all on its
own. One guy simply rewrote it (did reuse no line of it)
into several classes because it was hopelessly
unmaintainable. That took two months. Perhaps Noob
has something like that to port.

Victor Bazarov

unread,
Jun 25, 2015, 8:23:20 AM6/25/15
to
On 6/24/2015 8:51 PM, Richard wrote:
> [Please do not mail me a copy of your followup]
>
> n...@notvalid.com spake the secret code
> <kSHix.1247307$dT.6...@fx35.am4> thusly:
>
>> On 23/06/2015 01:02, alf.p.s...@gmail.com wrote:
>>> auto main() -> int {}
>>
>> heh, nice little trick I did not think before.... :) this works! new
>> form of main
>
> Meh. Might as well just write
>
> int main() {}
>
> The use of auto and -> here feels gratuitous.

It's not gratuitous if it makes you special. Like the :: in front of
'std'. ;-)

V
--
I do not respond to top-posted replies, please don't ask

Richard

unread,
Jun 25, 2015, 1:10:37 PM6/25/15
to
[Please do not mail me a copy of your followup]

David Brown <david...@hesbynett.no> spake the secret code
<mmga50$svu$1...@dont-email.me> thusly:

>[...] I'd be happy to try out other
>IDEs, such as NetBeans or CLion, if it looked like they would be
>significantly better for me - but it doesn't sound like there would be
>much difference.

I'd love it if some Eclipse user could evaluate my refactoring test
suite and tell me how good Eclipse is at refactoring:
<https://github.com/LegalizeAdulthood/refactor-test-suite>

woodb...@gmail.com

unread,
Jun 25, 2015, 5:22:02 PM6/25/15
to
On Thursday, June 25, 2015 at 6:04:48 AM UTC-5, Öö Tiib wrote:
> On Thursday, 25 June 2015 02:18:26 UTC+3, JiiPee wrote:
> > On 13/06/2015 18:33, Noob wrote:
> > >
> > > Your example is nice with 1 field. But the actual definition
> > > is more like this:
> > >
> > > class foo {
> > > public:
> > > int aa, bb, cc, ...
> > > int va[Na], vb[Nb], ...
> > > int v2a[N2a][Ma], v2b[N2b][Mb], ...
> > > bar *p1, baz *p2, ...
> > >
> > > foo();
> > > ~foo();
> > > 40 methods
> > > };
> > >
> > > Would it still look simple then?
> > >
> >
> > 40 methods in a class ? :) maybe a bit too much... there should be only
> > a few in a class normally?
>
> 10-15 member functions in class is quite livable but 40 is
> smelly (too lot of responsibilities) and should be perhaps
> split up.
>

Well, std::string has I think over 40 member functions. It's
considered to be a mess I guess, but the only thing I can
think of to make it better would be to remove either the size
or length member function that do the same thing. And I'm
guilty of asking for a function to be added to the class. I'd
like to see a constructor added that takes a char const* and an
integer for how many more bytes beyond the length of the char
const* to allocate.

Brian
Ebenezer Enterprises - In G-d we trust.
http://webEbenezer.net

Öö Tiib

unread,
Jun 25, 2015, 9:20:20 PM6/25/15
to
'std::string' is that monster perhaps because of programmers who *expect*
the string classes to have *member* *functions* for doing outright any
text and/or container management operations imaginable.

'std::string' is not too large in that sense; QString for example has
over 200 public non-static member functions plus tens of operators (both
member and non-member) and pile of static member functions. I haven't
really counted but can be like 300 all together.

Similar would feel some 'number' class that would contain all possible
math functions as member functions. Math functions we fortunately expect
to be non-members.

> And I'm
> guilty of asking for a function to be added to the class. I'd
> like to see a constructor added that takes a char const* and an
> integer for how many more bytes beyond the length of the char
> const* to allocate.

See! Indeed, everyone has some sort of particular narrow use-case
for what there would be convenient to have some tiny bit different
function. Your's is particularly unusual ... I trust I haven't seen
that one in any library ... QString certainly does not have it.

Daniel

unread,
Jun 26, 2015, 5:12:41 AM6/26/15
to
On Thursday, June 25, 2015 at 9:20:20 PM UTC-4, Öö Tiib wrote:
>
> 'std::string' is that monster perhaps because of programmers who *expect*
> the string classes to have *member* *functions* for doing outright any
> text and/or container management operations imaginable.

It's unfortunate std:string has mutators, could have saved massive amounts of discussion on std.c++ regarding COW implementation. Also incongruent that it has some member functions that only make sense when the stored octets are ascii, given emerging practice of putting UTF8 octets in there.
>
> 'std::string' is not too large in that sense; QString for example has
> over 200 public non-static member functions plus tens of operators (both
> member and non-member) and pile of static member functions.

Yes, but QString aspires to support string semantics, whereas std::string aspires to be little more than an array of bytes.

> Similar would feel some 'number' class that would contain all possible
> math functions as member functions.

Indeed. There used to be a chorus of OO people that insisted that sin, cos, etc had to be be members, but we don't hear much from them anymore.

>Math functions we fortunately expect
> to be non-members.
>
I gather you don't care for extension methods :-)

Daniel

woodb...@gmail.com

unread,
Jun 26, 2015, 1:52:29 PM6/26/15
to
I don't think it's a narrow use-case. When I throw an exception
I often have an idea of how many additional bytes are going to
be added to the string. So the following:

if (argc!=2)
throw failure("Usage: ") << *argv << " config-file-name";

would be changed to this:


if (argc!=2)
throw failure("Usage: ", 30) << *argv << " config-file-name";

The underlying string would have a capacity of at least 37 (7 for
"Usage: "). That would avoid having to make more allocations
for the pieces as they are added and copying after the allocations.
I'm hoping this will make it into std::string implementations.


Brian
Ebenezer Enterprises - "You are the light of the world. A city on
a hill cannot be hidden." Yeshua (aka Jesus) speaking to his followers.

http://webEbenezer.net
It is loading more messages.
0 new messages