Related
Is this considered as bad style (doing new in the header outside of a construcor)?
class ClassName : public QWidget
{
Q_OBJECT
public:
explicit ClassName(QWidget* parent = 0);
CustomList<Identifier*>*const identifier_list = new CustomList<Identifier*>("someString");
};
What I want to achieve by this is to not have to write if (identifier_list == NULL) everywhere. Like this the identifier_list cannot be NULL.
That will of course only work in C++11 and above, due to the default member initializer. However, by writing this, you are now required to provide (or =delete) your copy/move constructors and assignment operators. Not to mention a destructor to delete this memory.
Which means you must decide on what copying behavior you want to have. Do you want to allow copying at all (and if not, you must use =delete to signify that)? If so, what should a copy do? Since it's a pointer-const, you can't copy the pointer itself. At least, not in the copy-assignment case. So if you're copying, you now must copy the pointed-to object.
And thanks to your pointer-const, movement is flat-out impossible (without a const_cast). So your move constructor/assignment will have to move the CustomList<Identifier*> object, not merely the pointer to it.
Also, because of all of these user-defined operations, your ClassName will no longer be considered a trivially copyable type. Though given that it stores a linked list, it probably wouldn't be trivially copyable either way.
So is this considered bad style? All things being equal, yes. Unless you have a genuine, well-considered reason to use a dynamic allocation, it's better and ultimately much safer programming style to just make it a value rather than a pointer:
CustomList<Identifier*> identifier_list("someString");
With the new standard, there are new ways of doing things, and many are nicer than the old ways, but the old way is still fine. It's also clear that the new standard doesn't officially deprecate very much, for backward compatibility reasons. So the question that remains is:
What old ways of coding are definitely inferior to C++11 styles, and what can we now do instead?
In answering this, you may skip the obvious things like "use auto variables".
Final Class: C++11 provides the final specifier to prevent class derivation
C++11 lambdas substantially reduce the need for named function object (functor) classes.
Move Constructor: The magical ways in which std::auto_ptr works are no longer needed due to first-class support for rvalue references.
Safe bool: This was mentioned earlier. Explicit operators of C++11 obviate this very common C++03 idiom.
Shrink-to-fit: Many C++11 STL containers provide a shrink_to_fit() member function, which should eliminate the need swapping with a temporary.
Temporary Base Class: Some old C++ libraries use this rather complex idiom. With move semantics it's no longer needed.
Type Safe Enum Enumerations are very safe in C++11.
Prohibiting heap allocation: The = delete syntax is a much more direct way of saying that a particular functionality is explicitly denied. This is applicable to preventing heap allocation (i.e., =delete for member operator new), preventing copies, assignment, etc.
Templated typedef: Alias templates in C++11 reduce the need for simple templated typedefs. However, complex type generators still need meta functions.
Some numerical compile-time computations, such as Fibonacci can be easily replaced using generalized constant expressions
result_of: Uses of class template result_of should be replaced with decltype. I think result_of uses decltype when it is available.
In-class member initializers save typing for default initialization of non-static members with default values.
In new C++11 code NULL should be redefined as nullptr, but see STL's talk to learn why they decided against it.
Expression template fanatics are delighted to have the trailing return type function syntax in C++11. No more 30-line long return types!
I think I'll stop there!
At one point in time it was argued that one should return by const value instead of just by value:
const A foo();
^^^^^
This was mostly harmless in C++98/03, and may have even caught a few bugs that looked like:
foo() = a;
But returning by const is contraindicated in C++11 because it inhibits move semantics:
A a = foo(); // foo will copy into a instead of move into it
So just relax and code:
A foo(); // return by non-const value
As soon as you can abandon 0 and NULL in favor of nullptr, do so!
In non-generic code the use of 0 or NULL is not such a big deal. But as soon as you start passing around null pointer constants in generic code the situation quickly changes. When you pass 0 to a template<class T> func(T) T gets deduced as an int and not as a null pointer constant. And it can not be converted back to a null pointer constant after that. This cascades into a quagmire of problems that simply do not exist if the universe used only nullptr.
C++11 does not deprecate 0 and NULL as null pointer constants. But you should code as if it did.
Safe bool idiom → explicit operator bool().
Private copy constructors (boost::noncopyable) → X(const X&) = delete
Simulating final class with private destructor and virtual inheritance → class X final
One of the things that just make you avoid writing basic algorithms in C++11 is the availability of lambdas in combination with the algorithms provided by the standard library.
I'm using those now and it's incredible how often you just tell what you want to do by using count_if(), for_each() or other algorithms instead of having to write the damn loops again.
Once you're using a C++11 compiler with a complete C++11 standard library, you have no good excuse anymore to not use standard algorithms to build your's. Lambda just kill it.
Why?
In practice (after having used this way of writing algorithms myself) it feels far easier to read something that is built with straightforward words meaning what is done than with some loops that you have to uncrypt to know the meaning. That said, making lambda arguments automatically deduced would help a lot making the syntax more easily comparable to a raw loop.
Basically, reading algorithms made with standard algorithms are far easier as words hiding the implementation details of the loops.
I'm guessing only higher level algorithms have to be thought about now that we have lower level algorithms to build on.
You'll need to implement custom versions of swap less often. In C++03, an efficient non-throwing swap is often necessary to avoid costly and throwing copies, and since std::swap uses two copies, swap often has to be customized. In C++, std::swap uses move, and so the focus shifts on implementing efficient and non-throwing move constructors and move assignment operators. Since for these the default is often just fine, this will be much less work than in C++03.
Generally it's hard to predict which idioms will be used since they are created through experience. We can expect an "Effective C++11" maybe next year, and a "C++11 Coding Standards" only in three years because the necessary experience isn't there yet.
I do not know the name for it, but C++03 code often used the following construct as a replacement for missing move assignment:
std::map<Big, Bigger> createBigMap(); // returns by value
void example ()
{
std::map<Big, Bigger> map;
// ... some code using map
createBigMap().swap(map); // cheap swap
}
This avoided any copying due to copy elision combined with the swap above.
When I noticed that a compiler using the C++11 standard no longer faults the following code:
std::vector<std::vector<int>> a;
for supposedly containing operator>>, I began to dance. In the earlier versions one would have to do
std::vector<std::vector<int> > a;
To make matters worse, if you ever had to debug this, you know how horrendous are the error messages that come out of this.
I, however, do not know if this was "obvious" to you.
Return by value is no longer a problem. With move semantics and/or return value optimization (compiler dependent) coding functions are more natural with no overhead or cost (most of the time).
Could someone please explain what is meant by the following?
You must define a default constructor if your class defines member variables and has no other constructors. Otherwise the compiler will do it for you, badly.
What are they referring to as "badly"?
From the expansion of that link:
"The reason for this is that if you
have no other constructors and do not
define a default constructor, the
compiler will generate one for you.
This compiler generated constructor
may not initialize your object
sensibly."
Might refer to how new T and new T() differ when there is no ctor provided.
It's good to be sure that the object is created in a known state. Primitive variables won't be set to zero by default, so you could end up with subtle bugs that don't always show up. By initializing the member variables to sensible variables, everything is much more predictable.
The only problem with the default constructor is that it initializes only what the compiler thinks must be initialized, and not what you may think needs to be initialized. Basically, that means that it will invoke initializers for objects with default initializers. It won't set pointers or simple types like int to sane values, etc. If that is sufficient, then the default constructor is not 'bad'. When it is insufficient, it is a bug (in your code) that you did not define the necessary default constructor with the correct initialization.
Take the Google style guide with a grain of salt -- or maybe a truckload of salt.
It is true that the compiler-generated default constructor won't necessarily initialize members that are of built-in types in a meaningful fashion. If you want that done, then yes, its failure to do that is bad. OTOH, if you don't want that done, then its doing it could be somewhat bad (wasteful) as well.
Bottom line: there are times to write your own default ctor, but they tend toward the exception, not the rule. Although there are simple rules of thumb to cover a lot of cases in C++ and will prevent a lot of problems, this really isn't one of them -- here you pretty much do need to know what the compiler-generated ctor will do, and what you want different if you're going to write your own.
In Debug build most compilers fill uninitialized space with some magic values, so that debugging is reliable. And providing custom constructor prevents certain POD optimizations.
In fact, it's a guideline just to make sure people does explicitely make the statement of what is an invalid or default state of any object.
That way, no surprise when reading the code, compared to the actual execution.
However, think that it's a company guideline, that is used to make sure everyone does follow the same rules, that's not a you-must-follow-it-because-google-does-it.
In fact, if you manage to make all your member objects being in valid state when default constructed, or force you to set a constructor, then there is no good reason for such a guideline.
If you have any primitive types as member variables (eg. int, float), then the default ctor will not initialize them. member variables that are a class type will have their default ctor's invoked.
Prefer member initializer lists, so your user supplied ctor may be empty:
class Foo {
int bar;
float baz;
Foo(): bar(0), baz(0.0f) { /* empty ctor body */ }
};
It won't set integers to 0 or pointers to null. It will run default constructors on object of types with constructors.
Some people would call it 'not sensible'.
It just seems a too simplified version of the rules of 3, you should either define yourself or leave the compiler version of
the copy constructor
the assignment operator
the destructor
(Note that by defining yourself a copy constructor, the compiler won't define a default constructor).
The default constructor built by the compiler does 'nothing', it will not even zero the memory occupied by the object
A few times, when refactoring code, I have forgotten to add the explicit keyword when adding a parameter to a previously-parameterless constructor, or removing parameters from a previously multi-parameter constructor. To prevent this, I have gotten in the habit of marking every constructor explicit, no matter no many arguments it has. (Except, of course, those constructors for which I actually want implicit conversion.)
Is there any downside to this? Performance? Compile time?
It doesn't have any downsides. It will be future safe, because in C++0x multi-parameter constructors participate in initializations using multi-element initializer lists and can forbidden to be used in the cases where only implicit conversions apply using explicit.
So if you find out a give multi-parameter constructor does not logically represent the value of your class, I think it's good to make it explicit (example: I would set a container constructor (size_t size, T defaultValue) be explicit, while the constructor of pair, (T first, U second) be set non-explicit).
I'm not sure, but I think it does have some unexpected consequences for the copy constructor to be explicit. Other than that, I think yo're OK.
There will be no runtime performance difference. The compile time difference is likely to be undetectable.
I think there is no harm in declaring all constructors with arguments explicit, except that it might look redundant for those with more than one argument.
If you declare a type with an explicit default constructor, you may have trouble using it with collection types.
Say I have a class, something like the following;
class MyClass
{
public:
MyClass();
int a,b,c;
double x,y,z;
};
#define PageSize 1000000
MyClass Array1[PageSize],Array2[PageSize];
If my class has not pointers or virtual methods, is it safe to use the following?
memcpy(Array1,Array2,PageSize*sizeof(MyClass));
The reason I ask, is that I'm dealing with very large collections of paged data, as decribed here, where performance is critical, and memcpy offers significant performance advantages over iterative assignment. I suspect it should be ok, as the 'this' pointer is an implicit parameter rather than anything stored, but are there any other hidden nasties I should be aware of?
Edit:
As per sharptooths comments, the data does not include any handles or similar reference information.
As per Paul R's comment, I've profiled the code, and avoiding the copy constructor is about 4.5 times faster in this case. Part of the reason here is that my templated array class is somewhat more complex than the simplistic example given, and calls a placement 'new' when allocating memory for types that don't allow shallow copying. This effectively means that the default constructor is called as well as the copy constructor.
Second edit
It is perhaps worth pointing out that I fully accept that use of memcpy in this way is bad practice and should be avoided in general cases. The specific case in which it is being used is as part of a high performance templated array class, which includes a parameter 'AllowShallowCopying', which will invoke memcpy rather than a copy constructor. This has big performance implications for operations such as removing an element near the start of an array, and paging data in and out of secondary storage. The better theoretical solution would be to convert the class to a simple structure, but given this involves a lot of refactoring of a large code base, avoiding it is not something I'm keen to do.
According to the Standard, if no copy constructor is provided by the programmer for a class, the compiler will synthesize a constructor which exhibits default memberwise initialization. (12.8.8) However, in 12.8.1, the Standard also says,
A class object can be copied in two
ways, by initialization (12.1, 8.5),
including for function argument
passing (5.2.2) and for function value
return (6.6.3), and by assignment
(5.17). Conceptually, these two
operations are implemented by a copy
constructor (12.1) and copy assignment
operator (13.5.3).
The operative word here is "conceptually," which, according to Lippman gives compiler designers an 'out' to actually doing memberwise initialization in "trivial" (12.8.6) implicitly defined copy constructors.
In practice, then, compilers have to synthesize copy constructors for these classes that exhibit behavior as if they were doing memberwise initialization. But if the class exhibits "Bitwise Copy Semantics" (Lippman, p. 43) then the compiler does not have to synthesize a copy constructor (which would result in a function call, possibly inlined) and do bitwise copy instead. This claim is apparently backed up in the ARM, but I haven't looked this up yet.
Using a compiler to validate that something is Standard-compliant is always a bad idea, but compiling your code and viewing the resulting assembly seems to verify that the compiler is not doing memberwise initialization in a synthesized copy constructor, but doing a memcpy instead:
#include <cstdlib>
class MyClass
{
public:
MyClass(){};
int a,b,c;
double x,y,z;
};
int main()
{
MyClass c;
MyClass d = c;
return 0;
}
The assembly generated for MyClass d = c; is:
000000013F441048 lea rdi,[d]
000000013F44104D lea rsi,[c]
000000013F441052 mov ecx,28h
000000013F441057 rep movs byte ptr [rdi],byte ptr [rsi]
...where 28h is the sizeof(MyClass).
This was compiled under MSVC9 in Debug mode.
EDIT:
The long and the short of this post is that:
1) So long as doing a bitwise copy will exhibit the same side effects as memberwise copy would, the Standard allows trivial implicit copy constructors to do a memcpy instead of memberwise copies.
2) Some compilers actually do memcpys instead of synthesizing a trivial copy constructor which does memberwise copies.
Let me give you an empirical answer: in our realtime app, we do this all the time, and it works just fine. This is the case in MSVC for Wintel and PowerPC and GCC for Linux and Mac, even for classes that have constructors.
I can't quote chapter and verse of the C++ standard for this, just experimental evidence.
Your class has a constructor, and so is not POD in the sense that a C struct is. It is therefore not safe to copy it with memcpy(). If you want POD data, remove the constructor. If you want non-POD data, where controlled construction is essential, don't use memcpy() - you can't have both.
You could. But first ask yourself:
Why not just use the copy-constructor that is provided by your compiler to do a member-wise copy?
Are you having specific performance problems for which you need to optimise?
The current implementation contains all POD-types: what happens when somebody changes it?
[...] but are there any other hidden nasties
I should be aware of?
Yes: your code makes certain assumptions that are neither suggested nor documented (unless you specifically document them). This is a nightmare for maintenance.
Also, your implementation is basically hacking (if it's necessary it's not a bad thing) and it may depend (not sure on this) on how your current compiler implements things.
This means that if you upgrade compiler / toolchain one year (or five) from now (or just change optimization settings in your current compiler) nobody will remember this hack (unless you make a big effort to keep it visible) and you may end up with undefined behavior on your hands, and developers cursing "whoever did this" a few years down the road.
It's not that the decision is unsound, it's that it is (or will be) unexpected to maintainers.
To minimize this (unexpectedness?) I would move the class into a structure within a namespace based on the current name of the class, with no internal functions in the structure at all. Then you are making it clear you're looking at a memory block and treating it as a memory block.
Instead of:
class MyClass
{
public:
MyClass();
int a,b,c;
double x,y,z;
};
#define PageSize 1000000
MyClass Array1[PageSize],Array2[PageSize];
memcpy(Array1,Array2,PageSize*sizeof(MyClass));
You should have:
namespace MyClass // obviously not a class,
// name should be changed to something meaningfull
{
struct Data
{
int a,b,c;
double x,y,z;
};
static const size_t PageSize = 1000000; // use static const instead of #define
void Copy(Data* a1, Data* a2, const size_t count)
{
memcpy( a1, a2, count * sizeof(Data) );
}
// any other operations that you'd have declared within
// MyClass should be put here
}
MyClass::Data Array1[MyClass::PageSize],Array2[MyClass::PageSize];
MyClass::Copy( Array1, Array2, MyClass::PageSize );
This way you:
make it clear that MyClass::Data is a POD structure, not a class (binary they will be the same or very close - the same if I remember correctly) but this way it is also visible to programmers reading the code.
centralize the usage of memcpy (if you have to change to a std::copy or something else) in two years you do it in a single point.
keep the usage of memcpy near the implementation of the POD structure.
You could use memcpy for copying array of POD types. And it will be a good idea to add static assert for boost::is_pod is true. You class is not a POD type now.
Arithmetic types, enumeration types, pointer types, and pointer to member types are POD.
A cv-qualified version of a POD type is itself a POD type.
An array of POD is itself POD.
A struct or union, all of whose non-static data members are POD, is itself POD if it has:
No user-declared constructors.
No private or protected non-static data members.
No base classes.
No virtual functions.
No non-static data members of reference type.
No user-defined copy assignment operator.
No user-defined destructor.
I will notice that you admit there is an issue here. And you are aware of the potential drawbacks.
My question is one of maintenance. Do you feel confident that nobody will ever include a field in this class that would botch up your great optimization ? I don't, I'm an engineer not a prophet.
So instead of trying to improve the copy operation.... why not try to avoid it altogether ?
Would it be possible to change the data structure used for storage to stop moving elements around... or at least not that much.
For example, do you know of blist (the Python module). B+Tree can allow index access with performances quite similar to vectors (a bit slower, admittedly) for example, while minimizing the number of elements to shuffle around when inserting / removing.
Instead of going in the quick and dirty, perhaps should you focus on finding a better collection ?
Calling memcpy on non-POD classes is undefined behaviour. I suggest to follow Kirill's tip for assertion. Using memcpy can be faster, but if the copy operation is not performance critical in your code then just use bitwise copy.
When talking about the case you're referring to I suggest you declare struct's instead of class'es. It makes it a lot easier to read (and less debatable :) ) and the default access specifier is public.
Of course you can use memcpy in this case, but beware that adding other kinds of elements in the struct (like C++ classes) is not recommended (due to obvious reasons - you don't know how memcpy will influence them).
As pointed out by John Dibling, you should not use memcpy manually. Instead, use std::copy. If your class is memcpy-able, std::copy will automatically do a memcpy. It may be even faster than a manual memcpy.
If you use std::copy, your code is readable and it always uses the fastest way to copy. And if you change the layout of your class at a later point so that it is not memcpy-able any more, the code that uses std::copy will not break, while your manual calls to memcpy will.
Now, how do you know whether your class is memcpy-able? In the same way, std::copy detects that. It uses: std::is_trivially_copyable. You can use a static_assert to make sure that this property is upheld.
Note that std::is_trivially_copyable can only check the type information. It does not understand the semantics. The following class is trivially copyable type, but a bitwise copy would be a bug:
#include <type_traits>
struct A {
int* p = new int[32];
};
static_assert(std::is_trivially_copyable<A>::value, "");
After a bitwise copy, the ptr of the copy will still point to the original memory. Also see the Rule of Three.
It will work, because a (POD-) class is the same as a struct (not completely, default access ...), in C++. And you may copy a POD struct with memcpy.
The definition of POD was no virtual functions, no constructor, deconstructor no virtual inheritance ... etc.