Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Returning a struct

Posted on 2006-03-26
12
Medium Priority
?
401 Views
Last Modified: 2013-12-14
Suppose you have a function that returns a struct, but doesn't take a struct as a parameter.  Is there a way to return all the struct values?

Something like:

typedef struct {
   char* word;
   int len;
}thing;

thing& func1(char* str)
{
   return { str, strlen(str); }  
}

The above code doesn't work, of course, but hopefully it shows what I'm trying to do.  func1 is a function of type thing, which is a struct - how can I return both values of struct from the function, and it is correct to pass a struct as a reference?
0
Comment
Question by:chsalvia
  • 4
  • 2
  • 2
  • +2
10 Comments
 
LVL 48

Accepted Solution

by:
AlexFM earned 1000 total points
ID: 16293571
You can return local variable by value:

thing func1(char* str)
{
    thing s;
    s.word = str;
    s.len = strlen(str);
    return s;
}

You can return pointer to allocated structure, client is responsible to release it:

thing* func1(char* str)
{
    thing* p = new thing();
    p->word = str;
    p->len = strlen(str);
    return p;
}

You cannot return reference to local variable which is destroyed when function exits. You can retun reference to global variable or class member, bt I don't think that this is what you want.
0
 
LVL 3

Expert Comment

by:leisner
ID: 16294019
AlexFM,

In this example:
thing func1(char* str)
{
    thing s;
    s.word = str;
    s.len = strlen(str);
    return s;
}
do you mean can or can't?   thing is on the stack, so it goes away when the
function goes out of scope -- which is a bug.

If you want to return multiple elements, you create temporary structures, or pass by reference....

Another way is for the caller to allocate the structure, pass down a pointer to it, and maybe the
calling function return status?

For example:

bool func1(thing *pthing, char *string)
{
    if(NULL == pthing || NULL == string)
        return false;
   pthing->word = strdup(string); // do you want the string or a copy to it?
   pthing->len = strlen(string) + 1; // add the NULL terminate?
   return true;
}

If you want  the return value to be the structure, you can use static instead of auto inside the
function -- but only one copy of the data is valid at one time.

0
 
LVL 48

Expert Comment

by:AlexFM
ID: 16294034
My first sample is OK, it doesn't return reference. It returns structure by value - this means, caller gets temporary structure instance which is assigned to it's variable:

thing t;
t = func1("bla");
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 3

Expert Comment

by:leisner
ID: 16295189
Yep, AlexPM, you're right.

But one caveat of that style of function calls -- you make an extra copy of the structure.
In this case the cost is minimal, but if you start  call to func1 repeatedly and thing is large, it gets expensive....

0
 
LVL 12

Expert Comment

by:rajeev_devin
ID: 16298450
>> But one caveat of that style of function calls -- you make an extra copy of the structure.
In that case don't return it. Do something like this

void func1(char* str, thing& t)
{
    t.word = str;
    t.len = strlen(str);
    return s;
}
0
 
LVL 11

Expert Comment

by:cup
ID: 16303703
I've had lots of problems with this particular style of programming

thing func1(char* str)
{
    thing s;
    s.word = str;
    s.len = strlen(str);
    return s;
}

especially in a multi-tasking environment.  I've seen it in a few books and some people swear by it but I wouldn't recommend returning anything other than a basic type or a pointer.  I've had no end of crashes when there are shallow copies and destructors delete pointers to arrays.  If you must use this style, do it this way

thing func1(char* str)
{
    static thing s;
    s.word = str;
    s.len = strlen(str);
    return s;
}

That way, you know the stack will not be wiped and no destructor will be called.  The only problem is that the result must be stored straight away and it is not thread safe.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 16307929
>>>> thing& func1(char* str) {  return { str, strlen(str); }   }

You could do the following:

thing& func(char* str)
{
     static thing s = { 0 };   // init
     thing t  = { str, strlen(str) };
     return s = t;
}

Here you return the static variable by reference (what isn't thread-safe as cup already told).

>>>> return s = t;

That invokes the (automatically generated) copy constructor of struct thing. However, it doesn't work in C but only in C++ cause there is no copy constructor in C. To make that clear I would change the definition of the struct to

struct thing
{
     char* psz;
     int     len;
};

BTW, I would not use the name 'word' for a string variable cause 'word' means a 16-bit integer.

Regards, Alex


0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 16307941
>>>> That invokes the (automatically generated) copy constructor of struct thing.

It is the assignment operator that is invoked, *not* the copy constructor.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 16307996
>>>> but if you start  call to func1 repeatedly and thing is large, it gets expensive....

Repeatedly means "millions of repetitions" before you actually could measure a difference.  The "expensive" argument came from times of 16-bit code where the stack was limited to some k bytes. If 'thing' is a structure where you have a few instances only, it doesn't matter - regarding effiency - whether it is passed by reference or by value. Actually, all modern container classes store by value (means they make copies from elements that were passed by value).

Regards, Alex

0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 16703620
>>>> Accept: AlexFM {http:#16293571}

Yes, that's a good decision.

Regards
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
Programmer's Notepad is, one of the best free text editing tools available, simply because the developers appear to have second-guessed every weird problem or issue a programmer is likely to run into. One of these problems is selecting and deleti…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
Suggested Courses

578 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question