Is this ever valid? Will the project compile? I do not have access to a compiler right now, but my friend had this in his code:
int returnTwice () {
return 1;
return 2;
}
Why and how is this inappropriate?
Thank you!
Thank you everyone that had something constructive to say.
It's partly valid.
The invalid part is that you try to declare a variable in an expression, which is not allowed. But there's nothing illegal by having multiple unconditional return statements, however only the first will be executed.
No, this isn't possible in C++ or any other programming language that I know of.
As another user who answered your question said, only the first return statement will be executed. Depending entirely on the compiler, it might give you an error or warning that you have two return functions in one defined scope, there is no syntax error here.
It is possible to return two or more values in C++ by placing each variable into a vector and returning it, as documented in this question.
A return returns the value assigned to it and exits the function.
In other programming languages such as Lua a return variable1, variable2; can be used.
It's not possible in C++. But, if you want a similar behaviour, you can use boost::tuple.
boost::tuple<double,double> figInfo(const Figure& fig)
{
double p = fig.getPerimeter();
double s = fig.getSurface();
return boost::make_tuple(p,s);
}
boost::tuple<std::string, unsigned short int, std::string> profile()
{
std::string first_name = "Christophe";
unsigned short int age = 29;
std::string address = "Unspecified";
return boost::make_tuple(first_name, age, address);
}
When a function returns, it stops executing. Everything after the first return executed will never get executed. Thus, you should get an "Error: unreachable code" for such a function.
Related
I'm very new to C++ and was wondering if there was a way to return integer input from a function directly without storing it in a variable.
To be more clear:
#include <iostream>
int function()
{
std::cin >> (return function here???)
}
int main()
{
int number = function()
std::cout << number
return 0;
}
Thanks for any help.
if there was a way to return integer input from a function directly without storing it in a variable.
There is not. All standard input interfaces take an object argument which they modify rather than return the resulting value1.
A possible reason for this design is that it is very typical for input to be bad. Only way to avoid returning an int from a function declared to return int is to throw (or terminate the process, but that would be silly). And input error is perhaps considered so non-exceptional that using exceptions for control flow of input handling may be considered inappropriate. This is just my reasoning, not an authoritative explanation for the design choice.
If you fix your function to be correct, with the variable that is necessary and checking for errors, then you can use that function to do exactly that:
return function();
1 With the exception of std::istream::get() and the corresponding C style std::getc and std::fgetc which you can use to extract a single character that they return directly.
Currently I am learning C++ with 6th edition C++ Primer Plus by Steven Prata and on p. 389 I found smth very interesting that I would like to clarify for myself.
If we have some function like this:
const std::string &ft_add_on_sides(std::string s1, std::string s2)
{
std::string res;
res = s2 + s1 + s2;
return (s2);
}
int main(void)
{
std::string input = "Hello"
std::string result = ft_add_on_sides(input, "###");
return (0);
}
As far as I understand, this function is expecting two string objects which will be copies of those, which programmer will actually pass. And this function will return const reference to some memory address.
But I am interested in return statement:
As s1 or s2 are located in a temporary storage, we can gain access to them, but when will they be destroyed? Won't I get into troubles with such return statement?
Add. Cause the variable can be destroyed and I am still asking for its address.
Parameters of a function are destroyed as soon as the return statement has executed, before the calling function continues. That means you can still use these parameters inside the return value expression, but you'd better return a copy of them.
What you wrote in your example is Undefined Behavior. Anything can happen. Typically, in debug modes compilers are reasonably good in catching accesses to destroyed strings, but in release builds the compiler no longer introduces code to catch bugs.
You can read the accepted answer here.
Return value of function
the return value is copied out of a local variable into the return register if necessary.
The functions' stack frame is no longer needed, the local variables are popped off and will not be accessible once the function returns, but s2 will be copied into the return register.
I am currently working my way through C++ Primer Fifth Edition. I have gone through a couple of other C++ books, but they weren't very detailed and were quite complicated.
This book has been helping me a lot with everything that I have missed. I've just hit a wall.
One of the exercises asks me to write a declaration for a function that returns a reference to an array of ten strings, without using trailing return, decltype, or type alias.
I know it only says write a declaration, which I have done, like so:
string (&returnArray()) [10];
I wanted to write a function definition as well, like so:
string (&returnString(int i, string s)) [10]
{
string s1[10];
s1[i] = s;
return s1;
}
In my main function, I have a for loop which passes a string literal through and stores that string inside a pointer to an array of ten strings. It should then output the results to the screen.
The problem I am having is, when I dereference my pointer to an array, once, it will output the address. If I dereference it twice, the program outputs nothing and stops responding.
Here is my main function, I have changed it multiple times, yet can't figure out why it's not outputting properly. I've probably got it all wrong...
int main()
{
string (*s)[10];
for(int i = 0; i != 10; ++i)
{
s = &returnString(i, "Hello");
cout << s[i] << endl;
}
return 0;
}
Your function returns a reference to a local variable – after the call, it’s a dangling reference. You cannot do that.
You can only return references to storage that goes on existing after the end of the function call.
Returning a reference to a temporary local object invokes undefined behavior.
A short fix is making it static:
string (&returnString(int i, string s)) [10]
{
static string s1[10];
^^^^^^
s1[i] = s;
return s1;
}
int main()
{
string(&s)[10] = returnString(0, "Hello");
for (int i = 0; i != 10; ++i)
{
s[i] = "Hello";
cout << s[i] << endl;
}
}
Returning pointers/references to local variables is bad, undefined behavior. You can follow your exercise and not forget that constraint, your exercise tells you to do something but it's not necessarily telling you to do it the wrong way, in fact it's a good one that will lead you to pitfalls and hence make you a better programmer once you figure them out.
So what's left given that constraint of not returning addresses to local variables but still addressing the task given? You have the static fix as M M. already mentioned, or you could think you're creating something useful like a function rotate, for example, that accepts an string(&)[10] and returns itself rotated ;-)
Look that, iostream insertion and extraction operators already work like that, returning references to parameters passed by reference.
I have a C++ class; this class is as follows:
First, the header:
class PageTableEntry {
public:
PageTableEntry(bool modified = true);
virtual ~PageTableEntry();
bool modified();
void setModified(bool modified);
private:
PageTableEntry(PageTableEntry &existing);
PageTableEntry &operator=(PageTableEntry &rhs);
bool _modified;
};
And the .cpp file
#include "PageTableEntry.h"
PageTableEntry::PageTableEntry(bool modified) {
_modified = modified;
}
PageTableEntry::~PageTableEntry() {}
bool PageTableEntry::modified() {
return _modified;
}
void PageTableEntry::setModified(bool modified) {
_modified = modified;
}
I set a breakpoint on all 3 lines in the .cpp file involving _modified so I can see exactly where they are being set/changed/read. The sequence goes as follows:
Breakpoint in constructor is triggered. _modified variable is confirmed to be set to true
Breakpoint in accessor is triggered. _modified variable is FALSE!
This occurs with every instance of PageTableEntry. The class itself is not changing the variable - something else is. Unfortunately, I don't know what. The class is created dynamically using new and is passed around (as pointers) to various STL structures, including a vector and a map. The mutator is never called by my own code (I haven't gotten to that point yet) and the STL structures shouldn't be able to, and since the breakpoint is never called on the mutator I can only assume that they aren't.
Clearly there's some "gotcha" where private variables can, under certain circumstances, be changed without going through the class's mutator, triggered by who-knows-what situation, but I can't imagine what it could be. Any thoughts?
UPDATE:
The value of this at each stage:
Constructor 1: 0x100100210
Constructor 2: 0x100100400
Accessor 1: 0x1001003f0
Accessor 2: 0x100100440
UPDATE2:
(code showing where PageTableEntry is accessed)
// In constructor:
_tableEntries = std::map<unsigned int, PageTableEntry *>();
// To get an entry in the table (body of testAddr() function, address is an unsigned int:
std::map<unsigned int, PageTableEntry *>::iterator it;
it = _tableEntries.find(address);
if (it == _tableEntries.end()) {
return NULL;
}
return (PageTableEntry *)&(*it);
// To create a new entry:
PageTableEntry *entry = testAddr(address);
if (!entry) {
entry = new PageTableEntry(_currentProcessID, 0, true, kStorageTypeDoesNotExist);
_tableEntries.insert(std::pair<unsigned int, PageTableEntry *>(address, entry));
}
Those are the only points at which PageTableEntry objects are stored and retrieved from STL structures in order to cause the issue. All other functions utilize the testAddr() function to retrieve entries.
UNRELATED: Since C++ now has 65663 questions, and so far 164 have been asked today, that means that only just today the number of C++ tagged questions exceeded a 16-bit unsigned integer. Useful? No. Interesting? Yes. :)
Either your debugger isn't reporting the value correctly (not unheard of, and even expected in optimized builds) or you have memory corruption elsewhere in your program. The code you've shown is more-or-less fine and should behave as you expect.
EDIT corresponding to your 'UPDATE2':
The problem is in this line:
return (PageTableEntry *)&(*it);
The type of *it is std::pair<unsigned const, PageTableEntry*>&, so you're effectively reinterpret-casting a std::pair<unsigned const, PageTableEntry*>* to a PageTableEntry*. Change that line to:
return it->second;
Keep an eye out for other casts in your codebase. Needing a cast in the first place is a code smell, and the result of doing a cast incorrectly can be undefined behavior, including manifesting as memory corruption as you're seeing here. Using C++-style casts instead of C-style casts makes it trivial to find where casts occur in your codebase so they can be reviewed easily (hint, hint).
std::map<>::find() returns an iterator which when dereferenced returns a std::map<>::value_type. The value_type in this case is a std::pair<>. You're returning the address of that pair rather than the PageTableEntry. I believe you want the following:
// To get an entry in the table (body of testAddr() function, address is an unsigned int:
std::map<unsigned int, PageTableEntry *>::iterator it;
it = _tableEntries.find(address);
if (it == _tableEntries.end()) {
return NULL;
}
return (*it).second;
P.S.: C-style casts are evil. The compiler would have issued a diagnostic with a C++ cast in place. :)
Try looking at the value of this at each breakpoint.
That copy constructor and assignment operator are both going to be used a lot if you're using STL containers. Maybe if you show us the code for those, we would see something wrong.
Could you add another unique value to the class to track the PageTableEntry s?
I know that I've had problems like this where the real problem was that there were multiple entries that looked the same and the breakpoints might switch PageTableEntry s without me realizing it.
I'm building a comparator for an assignment, and I'm pulling my hair out because this seems to simple, but I can't figure it out.
This function is giving me trouble:
int compare(Word *a, Word *b)
{
string *aTerm = a->getString();
string *bTerm = b->getString();
return aTerm->compare(bTerm);
}
Word::getString returns a string*
Error:
In member function `virtual int CompWordByAlpha::compare(Word*, Word*)':
no matching function for call to...
...followed by a bunch of function definitions.
Any help?
You're comparing a string to a string pointer, and that's not valid. You want
return aTerm->compare(*bTerm);
You aren't getting the different uses of the * operator. The use of the * in "string* bTerm = b->getString()" means "bTerm is a pointer to a string". The use of the * inside of compare(*bTerm) means "take the value of the location pointed to by bTerm" instead of just using compare(bTerm) which simply attempts to compare the value of bTerm itself, which is a hex address.
This is also happening on the left side of that call:
aTerm->compare(*bTerm); //this statement
(*aTerm).compare(*bTerm); //is the same as this statement
The -> operator just reduces the amount of typing required.
P.S.: This kind of stuff you could have easily figured out from Google or your programming textbook. Although others may disagree, I don't feel that questions about completely basic syntax have any place on Stack Overflow.