Suppose I hae to following:
int &f() {
static int x = 0;
return x;
}
void main() { f() = 5; }
I realize that this function returns a reference to an integer
(I have tried to use this Function returning int&).
Does it mean that x will be equal to 5 in this case?
I do not really realize what f() = 5in that...
In addition, what change could it make If would omit 'static' above?.
I know that static int is an integer which exist actually before the program exists, but I am not sure it helps me to understand what change would happen.
I am trying to find out the answers for that with using debugger.
Does it mean that x will be equal to 5 in this case?
Yes. After an integer has been assigned a value, it will be equal to that value.
what change could it make If would omit 'static' above?
Depends on how you intend the program to behave. Only removing static would make the program to have undefined behaviour, so that would not be a good idea. One possible change would be to remove the entire function declaration, and the call to it.
Related
I was reading "Beginning C++ Through Game Programming, Fourth Edition" when I found a section about to pass a reference as an argument in a function that says:
"Pass a reference only when you want to alter the value
of the argument variable. However, you should try to avoid changing
argument variables whenever possible."
Basically it says that I shoud avoid to do something like this:
void swap(int& x, int& y)
{
int temp = x;
x = y;
y = temp;
}
But, why should I avoid doing this?
I found very useful to create functions to change variables, because these functions keep my code organized avoiding me to write every variable change in the main() function, and they also avoid me to write the same code repeatedly.
What alternative is there if I should not do this?
With the case of swap, pass by reference shoud be used, because multiple variables are being changed in the function and the expected behavior of the function is obvious. If you were only changing one variable or have a function that should be returning a result, then it is better to return a value for the most part (With some exceptions). For example, supoose you had a function sum():
int sum(int a, int b)
{
return a + b;
}
Usage of this function might be:
int x = sum(1, 2); // Obvious and to the point
Since there is no need to change any of the variables, one would use pass by value here (Pass by const reference doesn't matter here, since POD types are pretty small). If you used pass by reference here, then the function would have changed to:
void sum(int a, int b, int& sum)
{
sum = a + b;
}
Usage of the function above might be:
int s;
sum(1, 2, s); // Obscure, unclear
Disadvantages of this are that it is unclear what the intent of the function is, and now the result of the function cannot be passed to another function in one line. So pass by reference should only be used when absolutely necessary.
On a side note, using a const reference for passing large objects to functions is always recommended, since it avoids a copy.
I understand that arrays need to have a const int to be initialized, so I have this in main. I want this in main because I want to be able to modify these numbers easily if necessary.
const int magicWordCount = 10;
compareWords(magicWordCount);
The declaration of this function is:
void compareWords(const int);
The definition:
void Words::compareWords(const int magicWordCount)
{
std::string magic[magicWordCount] = {};
convertToStringArray(magicBuffer, magicBufferLength);
}
When I do this, "magicWordCount" in the definition is underlined by intellisense telling me, expression must have a constant value. I'm confused on where the value is NOT constant. Thoughts?
Although magicWordCount is const, as far as the compiler knows, it is a run-time constant, not a compile-time constant. In other words, it can ensure that the value of magicWordCount is not going to be changed inside Words::compareWords.
That is not enough to declare an array with the specific size: the compiler (and intellisense) are asking for a compile-time constant; magicWordCount is not a compile-time constant.
You can avoid this problem by using std::vector instead of an array:
std::vector<std::string> magic(magicWordCount);
The above will work even without const.
You could put magicWordCount in your Word class header, above your definition of the class. It's still easily accessible there, and you won't have to pass it in as a function parameter anymore.
it is the problem about array
because array is store in local scope
which mean if it did not have a const size(define before compile) it could make buffer overflow attack
for example the const int magicWordCount = 1000
the size of string[] will absolutely cover the return point
so in this situation you might use pointer instead
string* str = (string*)malloc(sizeof(string*) * a);
for(int i = 0; i < a; i++){str[i] = "";}
and also for my opinion, never use array, and instead with pointer
because the array perform really bad performance and a strange logic on read/write
We got practice sheets for a test next week, for studying a little bit of C++ (still a beginner here). I still can't figure out a simple question.
That is, why are these snippets of code problematic?
int& p(int z) { return z; }
int* h(int z) { return &z; }
When int *h(int z) {return &z} is called, the parameter passed to the function is copied to a variable named z. That copy only lasts as long as the function. So once the function returns, it is no longer available to your program. So you can't have a valid pointer to it once the function returns: formally &z is invalidated.
The same is true for the reference version int &p(int z) {return z}.
As an exercise, see if you can figure out what would happen if z was itself a reference: i.e. int &p(int& z) {return z}. Then, a copy would not be taken. But do note that no professional would ever write a function like this.
The behavior of the returned value is undefined.The tricky thing here is that if you test your function with some kind of operation ( eg. printing to std output or assertion) you might often get an expected result but that doesn't mean it is safe since returned value is pointing to value written in the stack which could be wiped out at any given moment right after the function returns ( it is called stack unwinding). So, the rule of thumb is, don't return the address or reference to a locally defined variable of a function unless it was defined as static and why on earth would one prefer that unless situations force you? :-)
Both snippets pass a reference (or pointer in the second case) to temporary. Consider for example p(18). Where would 18 actually be stored? So where should p(18) point to?
Side note: If everything would be const, the code would be ok, ie.
int const & p(int const & input) { return input; }
The standard would guarantee it.
I have for example this:
void SetWidth(double width);
Should it be:
void SetWidth(const double width);
No, you shouldn't.
The compiler treats the two function signatures as identical, so about all you can accomplish by adding const in a case like this is mislead the reader. For one obvious example, a reader who doesn't know C++ quite so well might believe that having both:
void SetWidth(double) {}
void SetWdith(const double) {}
...would be legitimate function overloading. This, of course, is wrong -- as already noted, the compiler treats the two as identical, so this would simply violate the one definition rule.
The const does prevent you from modifying the parameter inside the function, but if your function is large enough that you think you need this (i.e., you're having difficulty keeping track of what's being modified and what isn't), then chances are pretty good that you need to rewrite the function.
From the caller's viewpoint, both are equivalent. You can (and, to reduce noise, should) leave that const out of a declaration, and only include it in the definition.
From the implementor's viewpoint, you might want to do it for the same reason you might want any local variable to be constant: to be sure that it won't change by accident.
For,
Void SetWidth(double width);
We can change the value of the variable width with in the function SetWidth(). But, the changed value will not reflect back to the called function. Say,
class A_Class
{
public:
void SetWidth(double width) {
width=width+10;
this._width=width;
std::cout<<"IN SetWidth:"<<width;
}
private:
double _width;
};
int main()
{
A_Class aObj;
double twidth=20.9;
aObj.SetWidth(twidth);
std::cout<<"twidth:"<<twidth;
return 0;
}
O/P: IN SetWidth:30.9
twidth:20.9
So, it doesn't matter if make it as const, which you have mentioned in the other proto-type [void SetWidth(const double width);].
Internally compiler allocates memory for 'width' variable in the stack and copies the value to that variable.
If you use the second proto-type[void SetWidth(const double width);] it ensures that variable width is constant can not be changed inside the function.
Hope this helps.
They are almost equivalent.
The only difference is that you tell to the compiler that the variable width cannot be modified inside the function scope when you use const.
Short answer: implement a function that takes a const argument by value when it makes sense to ensure (or explicitly express) that: "This argument will not change inside the body of this function."
and implement a function that will take const argument by reference, when you want to explicitly tell the caller: "This function will not change the argument you're passing to it."
(In case of the "setter" taking an argument by value - such as SetWidth - it doesn't make much of a sense to use const)
If the function is not expected to modify the local variable width, you should declare it const. This way, if you inadvertently try to assign to the variable, or assign its address to a non-const pointer (since that could allow it to be modified), the compiler will issue a warning.
There's no difference in the generated code in either case, it just enables these additional safety checks.
Note: I am using the g++ compiler (which is I hear is pretty good and supposed to be pretty close to the standard).
Not trying to start a grammar war, but just a random question... What is the ideal way to declare a pointer?
int* pI = 4;
int *pI = 4;
(or my favorite, I know it's non-pretty, but I like it):
int*pI = 4;
Same question stands for references:
int& rI = 4;
int &rI = 4;
or
int&rI = 4;
Maybe there is no right answer. Similarly, should I care whether a constant integer is declared as:
const int I = 4;
or
int const I = 4;
I'm fine with not caring...
I do like the way a const function is declared by having a const after the last parenthesis.
And I believe a constant function has a distinct function signature than the similar non-const function (i.e. the const-nesss is part of the function signature, unlike most sources that say it just depends on the arguments type and the return type).
Is this right? Should I care?
I prefer
int* a;
int& b;
for the following reason: the type is int* and not int. For me - the type belongs together and needs to stand separate from the name. I know this introduces some problems with
int* a, b;
but that's why I don't declare to variables in one line.
Other than that - like VJo said: stick to the coding standard. If everyone around you does it one way, don't do it the other.
Coding standards might tell you how to declare or define your variables.
Other then that, use whatever suits you better.
And I believe a constant function has a distinct function signature than the similar non-const function (i.e. the const-nesss is part of the function signature, unlike most sources that say it just depends on the arguments type and the return type).
A constant function has a keyword const which is appended at the end of it.
int doSomething() const;
It means that the function will not alter the state(members) of the class.
Mentioning const on an argument implies that the function will not alter the state of that variable(param in below example) being passed to the function.
int doSomething(const int param);
Mentioning const before the return type applies to the type being returned by the function.
const int doSomething();
Implies the function returns a const integer value.
So yes your understanding is correct. And there is no other way to declare a function const except putting a const after the last paranthesis.
Also, note that const member function can be only called on a const object, while a non const member function can be called by const as well as non const objects of that class.
As far as the way of declaring, Each organization have their own coding guidelines and you should stick to that, Yes there is no distinct advantage of using those contructs you mentioned in either way with respect to compiler optimization or treatment. Just follow what you like or what your organzation wants you to follow.
Bjarne Stroustrup uses:
int* a;
so, that's good enough for me.