cant return a string from function - c++

The problem i am having is when i compile my code, i get an error (uninitialized local variable "optionNumber used"
I am using visual studio 2017 on a macbook air for this.
here is my code:
#include "pch.h"
#include <iostream>
int runMenu(int optionNumber) {
std::cout << "Choose an option \n";
std::cout << "1) Create Array \n";
std::cout << "2) View Array \n";
std::cout << "3) Add/Delete Values \n";
std::cin >> optionNumber;
return(optionNumber);
};
int main()
{
int optionNumber;
int optionNum;
optionNum = runMenu(optionNumber);
std::cout << optionNum;
return(0);
}

int main()
{
int optionNumber;
^^^^^^^^^^^^^^^^
Here, you've declared a local variable. You've not provided an initialiser. Therefore the local integer has an indeterminate value. If you read an indeterminate value, the behaviour of your program will be undefined.
optionNum = runMenu(optionNumber);
^^^^^^^^^^^^
Here, you copy the variable whose value is indeterminate into an argument. Therefore the behaviour of the program is undefined. Luckily, your compiler noticed this mistake and warned about it.
Most trivial solution: Initialise the variable:
int optionNumber = 42;
On the other hand, you may want to think a bit about what you've written. The value that you pass to the function runMenu is never used in the function. Whatever value is passed in will be overwritten by whatever is extracted from standard input. The argument is completely pointless. Instead of an argument, you can read the input into a local variable:
int runMenu() {
// your std::cout stuff
int optionNumber;
std::cin >> optionNumber;

Related

Why a reference declaration influences my pointer?

Case 1
#include <iostream>
using namespace std;
int main() {
int n = 1;
// int & r = n;
int * p;
cout << &n << endl;
cout << p << endl;
return 0;
}
Output 1
0x7fffffffdc94
0
Case 2
#include <iostream>
using namespace std;
int main() {
int n = 1;
int & r = n;
int * p;
cout << &n << endl;
cout << p << endl;
return 0;
}
Output 2
0x7fffffffdc8c
0x7fffffffdd90
In Output 2, the pointer p just pointed to the address followed int n. Shouldn't an unintialized pointer point to some random places?
Why adding a reference declaration influences the address of p pointed to?
Shouldn't an unintialized pointer point to some random places?
No, an uninitialized pointer points nowhere. It has an indeterminate value. Trying to read and/or print this indeterminate pointer value as you are doing in
cout << p << endl;
has undefined behavior. That means there is no guarantee whatsoever what will happen, whether there will be output or not or whatever the output will be.
Therefore, there is no guarantee that changing any other part of the code doesn't influence the output you will get. And there is also no guarantee that the output will be consistent in any way, even between runs of the same compiled program or multiple compilations of the same code.
Practically, the most likely behavior is that the compiler will emit instructions that will simply print the value of whatever memory was reserved on the stack for the pointer. If there wasn't anything there before, it will likely result in a zero value. If there was something there before it will give you that unrelated value.
None of this is guaranteed however. The compiler can also just substitute the read of the pointer value with whatever suits it or e.g. recognize that reading the value has undefined behavior and that it may therefore remove the output statement since it can not be ever reached in a valid program.

The address always returned is 0 instead of the actual value

Here is the simple code:
int *ad_return()
{
int a=600;
cout << &a << endl;
return &a;
}
int main()
{
cout << ad_return();
return 0;
}
The output is unexpected. The first cout prints an address that looks like a address but the cout that is in the main prints a legit 0. I couldn't find an explanation anywhere.
Based on what I have experimented, I have concluded the following:
Since the address of a local variable that has already went out of scope is undefined, it seems that gcc and g++ decided to implement a feature that sets this to zero (probably to make sure that the code segfaults instead of generating thoroughly bizarre behaviour). It does not do this in clang, but the value is undefined so both of these compilers are operating in accordance with the standard.
Try This Code.
There was problem you were trying to access address of a local variable a it is not accessible out side of the function as_return(). So declare it in global so that it is accessible to everyone.
#include<iostream>
using namespace std;
int a;
int *ad_return()
{
a=600;
cout << &a << endl;
return &a;
}
int main()
{
cout << ad_return();
return 0;
}
.
I hope you got answer

Tutorial c++ reference parameters issue

I have some doubts about C++ reference parameters. I am learning from this website:
http://www.doc.ic.ac.uk/~wjk/c++Intro/RobMillerL3.html
First program:
#include<iostream>
using namespace std;
int area(int length, int width);
int main()
{
int this_length, this_width;
cout << "Enter the length: ";
cin >> this_length;
cout << "Enter the width: ";
cin >> this_width;
cout << "\n";
cout << "The area of a " << this_length << "x" << this_width;
cout << " rectangle is " << area(this_length, this_width) << endl;
return 0;
}
int area(int length, int width)
{
int number;
number = length * width
return number;
}
Then the author suggests that "under some circumstances, it is legitimate to require a function to modify the value of an actual parameter that it is passed".After that he introduces new function:
void get_dimensions(int& length, int& width)
{
cout << "Enter the length: ";
cin >> length;
cout << "Enter the width: ";
cin >> width;
cout << "\n";
}
What is the main advantage when we pass values as parameters?
Advantages of passing by reference:
It allows us to have the function change the value of the argument, which is sometimes useful.
Because a copy of the argument is not made, it is fast, even when used with large structs or classes.
We can pass by const reference to avoid unintentional changes.
We can return multiple values from a function.
Disadvantages of passing by reference:
Because a non-const reference can not be made to a literal or an expression, reference arguments must be normal variables.
It can be hard to tell whether a parameter passed by reference is meant to be input, output, or both.
It’s impossible to tell from the function call that the argument may change. An argument passed by value and passed by reference looks the same. We can only tell whether an argument is passed by value or reference by looking at the function declaration. This can lead to situations where the programmer does not realize a function will change the value of the argument.
Because references are typically implemented by C++ using pointers, and dereferencing a pointer is slower than accessing it directly, accessing values passed by reference is slower than accessing values passed by value.
Sources:
http://www.learncpp.com/cpp-tutorial/73-passing-arguments-by-reference/
http://www.functionx.com/cppcli/functions/Lesson10b.htm
https://en.wikibooks.org/wiki/C++_Programming/Code/Statements/Functions
There is already a good answer (imho worth accepting). However, I would like to give a more basic answer, as it seems like you encountered passing by reference for the first time:
This function:
void foo(int x){x +=1;}
can do anything with the value of the passed (by value) parameter, but it has no chance to return anything to the caller, i.e. the x+=1 has practically no effect at all.
On the other hand, this function:
void bar(int& x){x +=1;}
gets not only the value, but it is working on the actual variable that you pass as parameter (by reference). Thus the x+=1 has an effect also outside of the function.
Both functions in action:
int main(){
int a = 1;
foo(a); // foo gets a copy of a and increments its value
// a is still 1
bar(a); // bar directly increments the value of a
// a is now 2
}
This is the main difference of passing a parameters by reference (bar) vs passing by value (foo). The main advantage of passing by reference is that the value of the parameter needs not to be copied. (This is whypassing by value is usually done with a const reference. Passing a const reference is like passing the value because the value cannot be changed even if actually a reference is passed.) However, for more details I refer to Rohits answer.
int &a is a reference to any parameter passed to that function, You should always think of references as Alias to a variable (it is similar to a const pointer).
If your reference is not const you are allowed to changed and therefore change the content of the original variable.
It is useful for many reason first of all it can improve performances by avoiding doing copies when passing a parameter by reference, and it is also useful if you have a function that your expecting to return multiple results for example =:
int f (int &a,int &b,int &c,int&d);
int main
{
int first,second,third,result;
result = f(first,third,result);
}
All your int variables can be change within you function.

Why doesn't the compiler warn "returning address of local variable or temporary" when returning a local reference to a local variable?

This happens when compiling the following code in Visual Studio 2010. My question is: the C++ compiler will warn if a function return the address of a local variable, but why doesn't it warn when returning a local reference to a local variable?
Is it still wrong (returning a local reference to a local variable), but just that the compiler couldn't detect it? Examining the addresses of 'num' and 'r' reveal that they share the same memory location.
#include <iostream>
using namespace std;
int & intReference() {
int num = 5;
int &r = num;
cout << "\nAddress of num: " << &num;
//return num; // Compiler warning: C4172: returning address of local variable or temporary
return r; // No warning?
}
void main() {
int &k = intReference();
cout << "\nk = " << k; // 5
cout << "\nAddress of k: " << &k; // same address as num
char c;
cin.get(c);
}
Yes it's still wrong.
The compiler cannot detect all cases where you're doing dangerous (or illegal) things. It warns when it does find them, but it can't identify all cases (and doesn't have to).

C++ compiler warning(?) when passing uninitialized local variable to function

I'm very new to C++ so I'm hoping someone would shed some light. I came across several similar topics but I just need clarification.
So it seems it's valid to pass a local string that has been declared but not initialized to a function. But why does compiler complain when you try it with int or float??
Whether it's string, float, or int, memory address gets referenced when it is declared even tho it may be "garbage"
#include <iostream>
using namespace std;
void load(int);
int main()
{
int salary;
load(salary);
return 0;
}
void load(int sal)
{
cout << "your salary: " << endl;
cin >> sal;
cout << sal << endl;
}
If I declare int or float as global variable, it works as expected without any warnings.
So then is it a better practice to declare variable in global space (I hope not)?
So putting it in global, it works :
#include <iostream>
using namespace std;
int salary;
void load(int);
int main()
{
load(salary);
return 0;
}
void load(int sal)
{
cout << "your salary: " << endl;
cin >> sal;
cout << sal << endl;
}
ok, another example to show that uninitialized global variable works when passing to function as value : (going off of David's comment)
int foo;
int returnit(int j)
{
cout << "your salary";
cin >> j;
return j;
}
int main()
{
int k = returnit(foo);
cout << k;
return 0;
}
anyways, lesson here is to initialize primitive data types before passing to functions.
So it seems it's valid to pass a local string that has been declared but not initialized to a function. But why does compiler complain when you try it with int or float??
If by "string" you mean a std::string object, it's because objects are never uninitialized. When you do:
std::string s;
then the default constructor of std::string is invoked, and the object is initialized.
Variables of primitive data types (such as int and float), unless declared to have static storage duration, will have garbage if not explicitly initialized, however. Making attempts to read and use that garbage rightly trigger warnings. (Variables of primitive data types that do have static storage duration (i.e., global variables or variables declared as static) are implicitly initialized to 0.)
So then is it a better practice to declare variable in global space (I hope not)?
No, a better practice would be to initialize your variables.
The best way to explain why you should never use an uninitialized variable in a function call is because this is logically invalid and sometimes both logically invalid and the syntax is invalid.
To see if your program is logically valid use the box method and trace your program. Global box has global variables in it, int main has its own box which holds its local variables, and when functions are called create a new box for that function and fill it with its parameters and local variables. Go line by line and change variable values as they change in the program. Remember to use only constants as global variables. When writhing a function be careful when you pass by reference that you understand that the function is given that variables address in memory and can change that value. When using pass by value use this kind of syntax in your functions declaration:
int Multiplication(const int Var1, const int Var2);
This protects the values you pass to multiplication.The syntax of c++ is made for speed, and it does not keep you from being logically incorrect.
int salary;
load(salary);
What value do you think you are passing to load here? You're passing a nonsense value.
To be clear, you are not passing an "uninitialized variable", you are passing the value of an uninitialized variable. If you do:
int j=3;
load(j);
You are passing the value of j, that is, 3, to load. If you don't specify otherwise, C++ passes by value.
You'd have the same problem with a global variable:
int foo;
int returnit(int j)
{
return j;
}
int main(void)
{
int j=returnit(foo);
What value do you think j should have here?! You still have to initialize a variable to some particular value before you can pass its value to a function.
To add on David's answer, what you probably wanted to do (I'm guessing) is to modify the original salary variable. To do this you need to pass a reference to the variable, like this:
void load(int& sal)
{
cout << "your salary: " << endl;
cin >> sal;
cout << sal << endl;
}
Note the '&' after int in the function signature.
Also note that you use 'salary' in load() where it's not defined. You should use 'sal' instead.
That way the compiler knows that load() receives a reference to a variable, so if you modify it inside the function, the variable you sent to the function (salary) also changes.
The call itself to the function remains the same.