I am trying this code in Visual Studio 2015 v4.
using namespace std;
void * operator new(size_t size) {
cout << "Creating new " << endl;
void * p = malloc(size);
return p;
}
class CTest {
private:
string a;
string b;
public:
CTest( const string &&one , const string && two ) :a(move(one)), b(move(two)) {}
};
int main() {
CTest("one", "one" );
return 0;
}
This code outputs "Creating new" 4 times in Visual studio , which means it allocates memory 4 times. However following semantics it should only allocate twice ( creating 2 literals in data segment , creating one and two function argument = 2 allocs , and then moving their resource to a and b member variable )
Compiling this under g++ outputs "Creating new" twice, as it should.
Is there any settings i need to set in order for VS to follow moving semantics? It should be supported by default as far as i know.
Thanks for help.
There are several issues here:
1) std::move does not move, especially if you pass by const &&. See answers here and here.
2) Every std::string implementation I am aware of uses small buffer optimization. Such implementations will never allocate when constructed with short strings (such as "one").
3) The standard library runtime is allowed to call operator new during static initialization, for instance to setup std::cout. The allocations you see are most likely not related to the string constructor or (lack of) move.
The arguments one and two are rvalue references to constant std::string objects. How can you move from a constant object?
Drop the const qualifier for the arguments. In most cases using the const qualifier doesn't make sense for rvalue references.
Or don't use either const nor rvalue references (and the compiler should create the correct code anyway).
Related
This question already has answers here:
Sell me const-correctness
(16 answers)
Closed 2 years ago.
What is the point of using the keyword const? for example when making a game, one of the first things to do is to set the width and height of it. And most of the time you'll use for example:
const int Width
and
const int height
Now I know that you should do it like that because the width and height of the screen will not change throughout the game, but what is the point of doing so ? you can do the same thing without using const and it will work just fine.
That was just an example. so what I'm confused about right now is:
What is the point of using the const keyword anywhere if you won't change the variable anyway?
Non-exhaustive list of reasons:
Software Engineering (SWE). SWE is not just programming, but programming with other people and over time.
const allows to explicitly express an invariant, which lets you and others reason about the code. As the program becomes bigger, these invariants cannot be just memorized. That's why encoding them in the programming language helps.
Optimization opportunities.
With the knowledge that certain values will not change, the compiler can make optimizations that would not be possible otherwise. To take this to the max, constexpr means that a value will be known at compile time, not just at run-time. This becomes even more important in potentially multi-threading contexts.
Example:
What kind of optimization does const offer in C/C++?
I leave out whole program analysis which would require a much longer answer and almost certainly is not applicable to generic C++ programs. But whole-program-analysis will allow reasoning of the analyzer or compiler about constness of variables as they get passed between functions, translation units and libraries.
Without const, you have to remember to not change the variable. The larger your program becomes, the harder it gets.
It also has some other useful effects:
const int a = 10;
int b[a]; // Doesn't work if `a` is not `const`.
// ...
void foo(const int &a) {};
void bar()
{
foo(42); // Doesn't work if the parameter is a non-const reference.
}
Having something declared const, compared to a value set with #define for instance, allows you to declare something that the compiler will never let you alter, but that will still keep all of the other properties of a regular variable.
In particular, it will keep a certain place in memory and a pointer on it can be obtained with « & », keeping all read-only routines that use to work on regular object compatible with it.
It's especially useful when your constant object is not a simple native type variable, but rather a complicated object spawned from a class and that still need to be initialized through a constructor.
Also remember that const is a type qualifier, than can apply not only on variable declarations, but also on arguments of a function prototype. In this particular case, this will enable your function to accept both constant or variable arguments.
Such a constant argument could be, for example, a double-quoted "string", which is const char *-typed, because the string is directly part of the code itself and defined at compilation type. Without a const qualifier, nothing could prevent your function from trying to write in it, nor warn the programmer that it's forbidden.
To stay with your example, suppose I write a game library that has a
struct game {
int width;
int height;
int area;
game(int w, int h) : width(w),height(h),area(w*h) {}
};
Now you use my library and because I did not write any documentation (evil me) you just start writing code and try what you can do with that class. You write code
#include <iostream>
int main() {
game g{3,5};
g.width = 12;
std::cout << g.width << " * " << g.height << " == " << g.area;
}
and get output:
12 * 5 == 15
You will complain that the code I wrote is broken because you get non-sense results when you use it. If however I had used const for things you are not supposed to modify:
struct game {
const int width;
const int height;
const int area;
game(int w, int h) : width(w),height(h),area(w*h) {}
};
Then you would get a nice error message that tells you that you tried to modify something that you are not supposed to modify:
prog.cc: In function 'int main()':
prog.cc:11:15: error: assignment of read-only member 'game::width'
g.width = 12;
Once you fixed your code to
#include <iostream>
int main() {
game g{3,5};
std::cout << g.width << " * " << g.height << " == " << g.area;
}
All const could be removed and the output would not change. However this is not always the case. For example member functions can have const and non-const overloads that can do different things depending on whether the method is called on a const or on a non-const object:
#include <iostream>
struct foo {
void sayHello() const {
std::cout << "I am a const object\n";
}
void sayHello() {
std::cout << "I am a non-const object\n";
}
};
int main() {
const foo f;
f.sayHello();
foo g;
g.sayHello();
}
output:
I am a const object
I am a non-const object
Conclusion:
const is mainly to ensure correctnes and to avoid mistakes. const can also be used to make const objects behave differently than non const objects. There is more to it and details you can read up eg here.
const is for a constant variable, that it means nobody should change it, or maybe for const T & passing non-trivial type as parameter, or maybe for making a pointer constant, or for value pointed from the pointer (const *P *variable)
Q1:
I have recently read book C++ Primer, when I read follow:
To substitute the value for the variable, the compiler has to see the variable’s initializer. When we split a program into multiple files, every file that uses the const must have access to its initializer. In order to see the initializer, the variable must be defined in every file that wants to use the variable’s value.
I have a question: when I use a variable defined in other file, I just use extern to declare is enough, why should I must have access to its initializer, so I have done a test:
in main.cpp, I write below:
#include <iostream>
using namespace std;
extern int test;
int main()
{
cout << test << endl;
return 0;
}
in test.cpp, I write below:
int test = 100;
and by the way, these two files are added in the same projects, or it will not build successful.
When I run them, it print
100
like I expect. But in main.cpp, I don't need to define something like int test = 100 like book said. I don't know who is right.
Q2:
int i = 43;
const int &r = i;
i = 1; //when i changed, r alse changed
I have tested in gcc 4.7 and visual studio 2013, they both get same result,
r changed. Then, what's the point of const? Shouldn't r always be 43?
I think the quote from the book means something like the following
const size_t N = 10;
int main()
{
int a[N];
//...
}
If the constant N is defined in some other module with specifier extern then in the module with main the compiler does not have an access to the value of the constant and as result it is unable to define the array
extern const size_t N;
int main()
{
int a[N]; // error: the value N is unknown
//...
}
By this reason constants have internal linkage that it could be possible to define them in each module where their values are required at compile time.
As for the second question then constant references are used that to prevent modifying the referenced objects using references.
For example if you want that some function would not change your compound object you can declare its parameter as a constant reference to the object.
Also a temporary objects are bound to constant references.
Consider an example
void display_string( const std::string &s )
{
std::cout << s << std::endl;
}
you may call the function using a character array. For example
display_string( "Hello, World" );
The compiler implicitly converts the string literal to a temporary object of type std::string and binds it to the constant reference of the parameter.
If the parameter would not be declared like constant reference as for example
void display_string( std::string &s );
then the compiler would issue an error.
Using a constant reference it is supposed that the client code will not change the referenced object itself.
That is the client code may look at the object but may not touch it by hands.:)
Q1. have access to its initializer means compiler need to known the variable's initializer(definition). You can let compiler achieve that by link main.cpp and test.cpp together. You said that these two files are added in the same projects, so IDE will do that for you.
You can find more on this question.
Q2. Compiler don't allow you to change r's value, because it's a reference to a const variable, but i is an integer variable, so you can change it's value.
I have a function which modifies std::string& lvalue references in-place, returning a reference to the input parameter:
std::string& transform(std::string& input)
{
// transform the input string
...
return input;
}
I have a helper function which allows the same inline transformations to be performed on rvalue references:
std::string&& transform(std::string&& input)
{
return std::move(transform(input)); // calls the lvalue reference version
}
Notice that it returns an rvalue reference.
I have read several questions on SO relating to returning rvalue references (here and here for example), and have come to the conclusion that this is bad practice.
From what I have read, it seems the consensus is that since return values are rvalues, plus taking into account the RVO, just returning by value would be as efficient:
std::string transform(std::string&& input)
{
return transform(input); // calls the lvalue reference version
}
However, I have also read that returning function parameters prevents the RVO optimisation (for example here and here)
This leads me to believe a copy would happen from the std::string& return value of the lvalue reference version of transform(...) into the std::string return value.
Is that correct?
Is it better to keep my std::string&& transform(...) version?
There's no right answer, but returning by value is safer.
I have read several questions on SO relating to returning rvalue references, and have come to the conclusion that this is bad practice.
Returning a reference to a parameter foists a contract upon the caller that either
The parameter cannot be a temporary (which is just what rvalue references represent), or
The return value won't be retained past the the next semicolon in the caller's context (when temporaries get destroyed).
If the caller passes a temporary and tries to save the result, they get a dangling reference.
From what I have read, it seems the consensus is that since return values are rvalues, plus taking into account the RVO, just returning by value would be as efficient:
Returning by value adds a move-construction operation. The cost of this is usually proportional to the size of the object. Whereas returning by reference only requires the machine to ensure that one address is in a register, returning by value requires zeroing a couple pointers in the parameter std::string and putting their values in a new std::string to be returned.
It's cheap, but nonzero.
The direction currently taken by the standard library is, somewhat surprisingly, to be fast and unsafe and return the reference. (The only function I know that actually does this is std::get from <tuple>.) As it happens, I've presented a proposal to the C++ core language committee toward the resolution of this issue, a revision is in the works, and just today I've started investigating implementation. But it's complicated, and not a sure thing.
std::string transform(std::string&& input)
{
return transform(input); // calls the lvalue reference version
}
The compiler won't generate a move here. If input weren't a reference at all, and you did return input; it would, but it has no reason to believe that transform will return input just because it was a parameter, and it won't deduce ownership from rvalue reference type anyway. (See C++14 §12.8/31-32.)
You need to do:
return std::move( transform( input ) );
or equivalently
transform( input );
return std::move( input );
Some (non-representative) runtimes for the above versions of transform:
run on coliru
#include <iostream>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
using namespace std;
double GetTicks()
{
struct timeval tv;
if(!gettimeofday (&tv, NULL))
return (tv.tv_sec*1000 + tv.tv_usec/1000);
else
return -1;
}
std::string& transform(std::string& input)
{
// transform the input string
// e.g toggle first character
if(!input.empty())
{
if(input[0]=='A')
input[0] = 'B';
else
input[0] = 'A';
}
return input;
}
std::string&& transformA(std::string&& input)
{
return std::move(transform(input));
}
std::string transformB(std::string&& input)
{
return transform(input); // calls the lvalue reference version
}
std::string transformC(std::string&& input)
{
return std::move( transform( input ) ); // calls the lvalue reference version
}
string getSomeString()
{
return string("ABC");
}
int main()
{
const int MAX_LOOPS = 5000000;
{
double start = GetTicks();
for(int i=0; i<MAX_LOOPS; ++i)
string s = transformA(getSomeString());
double end = GetTicks();
cout << "\nRuntime transformA: " << end - start << " ms" << endl;
}
{
double start = GetTicks();
for(int i=0; i<MAX_LOOPS; ++i)
string s = transformB(getSomeString());
double end = GetTicks();
cout << "\nRuntime transformB: " << end - start << " ms" << endl;
}
{
double start = GetTicks();
for(int i=0; i<MAX_LOOPS; ++i)
string s = transformC(getSomeString());
double end = GetTicks();
cout << "\nRuntime transformC: " << end - start << " ms" << endl;
}
return 0;
}
output
g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
Runtime transformA: 444 ms
Runtime transformB: 796 ms
Runtime transformC: 434 ms
This leads me to believe a copy would happen from the std::string&
return value of the lvalue reference version of transform(...) into
the std::string return value.
Is that correct?
The return reference version will not let std::string copy happened, but the return value version will have copy, if the compiler does not do RVO. However, RVO has its limitation, so C++11 add r-value reference and move constructor / assignment / std::move to help handle this situation. Yes, RVO is more efficient than move semantic, move is cheaper than copy but more expensive than RVO.
Is it better to keep my std::string&& transform(...) version?
This is somehow interesting and strange. As Potatoswatter answered,
std::string transform(std::string&& input)
{
return transform(input); // calls the lvalue reference version
}
You should call std::move manually.
However, you can click this developerworks link: RVO V.S. std::move to see more detail, which explain your problem clearly.
if your question is pure optimization oriented it's best to not worry about how to pass or return an argument. the compiler is smart enough to strech your code into either pure-reference passing , copy elision, function inlining and even move semantics if it's the fastest method.
basically, move semantics can benefit you in some esoteric cases. let's say I have a matrix objects that holds double** as a member variable and this pointer points to a two dimenssional array of double. now let's say I have this expression:
Matrix a = b+c;
a copy constructor (or assigment operator, in this case) will get the sum of b and c as a temorary, pass it as const reference, re-allocate m*namount of doubles on a inner pointer, then, it will run on a+b sum-array and will copy its values one by one.
easy computation shows that it can take up to O(nm) steps (which can be generlized to O(n^2)). move semantics will only re-wire that hidden double** out of the temprary into a inner pointer. it takes O(1).
now let's think about std::string for a moment:
passing it as a reference takes O(1) steps (take the memory addres, pass it , dereference it etc. , this is not linear in any sort).
passing it as r-value-reference requires the program to pass it as a reference, re-wire that hidden underlying C-char* which holds the inner buffer, null the original one (or swap between them), copy size and capacity and many more actions. we can see that although we're still in the O(1) zone - there can be actualy MORE steps than simply pass it as a regular reference.
well, the truth is that I didn't benchmarked it, and the discussion here is purely theoratical. never the less, my first paragraph is still true. we assume many things as developers, but unless we benchmark everything to death - the compiler simply knows better than us in 99% of the time
taking this argument into acount, I'd say to keep it as a reference-pass and not move semantics since it's backword compatible and much more understood for developers who didn't master C++11 yet.
int FunctionName(const char *pValueName, const char *pValueData, long iMaxValueSize)
{
char *pDataToStore = const_cast<char *>(pValueData);
int iActualSiz = ProcessData(pDataToStore, iMaxValueSize);
...
...
}
In the upper code snippet ProcessData() function modifies the char*, which it receives as parameter. Now even after assigning pValueData into pDataToStore, after ProcessData() get executed, value of pValueData is being same as pDataToStore.
My aim is to keep intact value of pValueData which is being passed as const char*
My aim is to keep intact value of pValueData which is being passed as
const char*
That's impossible. Passing via const means it cannot be modified, except when it was originally not constant.
Example:
char *ptr1 = new char[100]; // not const
char *ptr2 = new char[100]; // not const
int i = FunctionName(ptr1, ptr2, 123);
In this case, you could technically keep the const_cast. But what for? Just change your function parameters to take char *:
int FunctionName(char *pValueName, char *pValueData, long iMaxValueSize)
{
int iActualSiz = ProcessData(pValueData, iMaxValueSize);
// ...
}
However, you most likely want to be able to pass constant strings. For example string literals:
int i = FunctionName("name", "data", 123);
String literals are unmodifiable and thus require your function to take char const *. A later attempt to modify them causes undefined behaviour.
As you can see, the error is in the general architecture and code logic. You want to modify something and at the same time you do not want to allow to modify it.
The question is: What happens with your pDataToStore when ProcessData is done with it? Does the caller of FunctionName need to be aware of the modifications? Or is it just internal business of FunctionName?
If it's just internal business of FunctionName, then you can keep its signature intact and have ProcessData modify a copy of the passed data. Here is a simplified (not exception-safe, no error checks) example:
int FunctionName(const char *pValueName, const char *pValueData, long iMaxValueSize)
{
char *copy = new char[strlen(pValueData) + 1];
strcpy(copy, pValueData):
int iActualSiz = ProcessData(copy, iMaxValueSize);
// ...
delete[] copy;
}
The nice thing is that you can now massively improve the interface of FunctionName by hiding all the low-level pointer business. In fact, why use so many pointers at all when C++ standard classes can do all the work for you?
int FunctionName(std::string const &valueName, std::string const &valueData, long maxValueSize)
{
std::vector<char> copy(valueData.begin(), valueData.end());
int actualSize = ProcessData(©[0], maxValueSize);
// ...
// no more delete[] needed here
}
The std::vector<char> automatically allocates enough memory to hold a copy of valueData, and performs the copy. It fully automatically frees the memory when it is no longer needed, even if exceptions are thrown. And ©[0] (which in C++11 can be written as copy.data()) is guaranteed to yield a pointer to the internally used data, so that low-level C functions can modify the vector's elements.
(I've also taken the chance to remove the Microsoft-style Hungarian Notation. It's a failed experiment from the 90s, and you've even used it incorrectly, supposing that a leading i is supposed to indicate an int.)
The bottom line is really:
If you need a const_cast anywhere in your code to make it compile, then somewhere else there is at least either one const missing or one too much. A const_cast always makes up for a mistake in another piece of code. It is always a workaround and never a solution designed up front.
Well I have solved the issue by creating the heap memory.
char *pDataToStore = new char[iMaxValueSize];
memcpy(pDataToStore, pValueData, iMaxValueSize*sizeof(char));
int iActualSiz = ProcessData(pDataToStore, iMaxValueSize);
...
....
delete []pDataToStore;
You have to make a difference between a const qualified type and a const qualified object.
The standard states in section 7.1.6.1: cv-qualifiers: (cv = const or volatile)
A pointer or reference to a cv-qualified type need not actually point
or refer to a cv-qualified object, but it is treated as if it does; a
const-qualified access path cannot be used to modify an object even if
the object referenced is a non-const object and can be modified
through some other access path.
If your pointer points to a non const object, the casting away will enable you to modifiy the objet, but as someone told, you are lying to the user of your function.
It your pointer points to a real const object (i.e. in const protected memory), the compiler will compile your code, but you might have a segmentation fault, typical for undefined behaviour.
Here an example, using the fact that "Ordinary string literal (...) has type “array of n const char”, where n is the size of the string (...)" (see standard, section 2.14.5):
char *my_realconst = "This is a real constant string"; // pointer does not claim that it points to const object
(*my_realconst)++; // Try to increment the first letter, will compile but will not run properly !!
So if your function ProcessData() is legacy code that is only reading the data but has forgotten to mention a const in the parameter list, your cast-away will work. If your function is however altering the data, it might work or it might fail, depending how the data poitned to was created !
So try to avoid casting const away if you are not 100% sure of what the effects will be ! Better clone your object the hard way creating a temporary object and copying the content.
I propose you a small template to handle these kind of issues easily:
template <typename T>
class Buffer {
size_t sz; // size
T* addr; // pointed
public:
Buffer(const T*source, size_t l) : sz(l), addr(new T[l]) { std::copy(source, source + l, addr); } // allocate and copy
~Buffer() { delete[]addr; } // destroy memory
operator T* () { return addr; } // convert to pointer
};
You may use your existing code almost as is:
Buffer<char> pDataToStore(pValueData, iMaxValueSize); // create the automatic buffer
int iActualSiz = ProcessData(pDataToStore, iMaxValueSize); // automatic use of pointer to buffer
cout << "modified copy: " << pDataToStore << endl;
cout << "original: " << pValueData << endl;
The buffer will be automatically released once pDataToStore is no longer in scope.
If you have similar issues with wchar_t buffers or anything else, it will work as well.
For explanations on the evil of casting away const, see my other answer
What is more efficient: Call by pointer or by value? I think it is call by pointer, because passing a pointer to a variable does not use as much memory as creating a copy of a variable. Am I wrong?
main(){
int a, b;
a = 10;
b = 5;
gcf(&a, &b);
return 0;
}
int gcf(int* c, int* d){
int val1=*c;
int val2=*d;
//...
}
In nearly all code, as long as we're dealing with small/simple objects, the overhead of copying the object, vs. passing it as a pointer or reference is pretty small.
Obviously, if we make a std::string with a large chunk of text in it, it will take quite some time to copy it, relative to just passing a reference.
However, the primary objecting ANY TIME when writing code is to focus on correctness. If you have "large" objects, then use const Type &val if the value is not being modified - that way, you can't accidentally modify it. If the object is to be modified, then you NEED to use a reference or pointer to get the updates back to the caller of the function.
It is entirely possible to make code that runs noticeably slower with a reference than with a value. I was once looking into the performance of some code that we were working on, and found a function that looked something like this:
void SomeClass::FindThing(int &thing)
{
for(thing = 0; someVector[thing] != 42; thing++)
;
}
It really looks rather innocent, but since each update of thing means an indirect memory access [at least in the compiler we used, which was certainly not "rubbish"], it was taking quite a lot of time out of the entire process [it was also called twice as much as necessary].
I rewrote it as:
void SomeClass::FindThing(int &thing)
{
for(int i = 0; someVector[i] != 42; i++)
;
thing = i;
}
And the function ran about 4x faster. Taking out the second, unnecessary call, as well, and we ended up with about 30% faster runtime. This was in a "fonts benchmark", and this was one out of a several dozen functions involved in the "draw fonts to screen". It's scary how a simple, innocent looking function can make a BIG difference to performance.
For types smaller than the size of a pointer (e.g. int), passing by value is more efficient.
For types bigger than the size of a pointer (e.g. most struct or class instances), passing by reference is probably more efficient (only "probably" because on top of the cost of passing the parameter, potentially constructing an object, you incur the cost of dereferencing your parameter every time you use it).
More details about passing-by-value vs. passing-by-reference can be found in this question. More details about reference vs. pointer arguments can be found in that question.
In your example of code snippet
main(){
int a, b;
a = 10;
b = 5;
}
int gcf(int* c, int* d){
int rem;
int val1=*c;
int val2=*d;
//...
}
there is no any sense to pass variables a and b to the function indirectly using pointers if you are not going to change them. In this case the code is ineffective because that to get values of *c and *d the compiler will need to generate more instructions.
And you are wrong saying that
passing a pointer to a variable does not use as much memory as
creating a copy of a variable. Am I wrong?
Usually pointers are equal to or even larger than the size of type int. For exaple in a 64-bit system sizeof( int ) can be equal to 4 while sizeof( int * ) can be equal to 8.
There is a sense to pass an object indirectly by pointers (usually in C programs) when the size of the object is much larger than the size of the pointer.
In C++ instead of pointers usually references are used.
For example
#include <iostream>
#include <string>
inline void print_reverse( const std::string &s )
{
std::cout << std::string( s.rbegin(), s.rend() ) << std::endl;
}
int main()
{
std::string s( "Hello World" );
print_reverse( s );
}
Here const std::string &s defined reference to an object of type std::string.