Thread: Can a function return char variable?

  1. #1
    Registered User
    Join Date
    Jul 2010
    Posts
    6

    Arrow Can a function return char variable?

    Can a function return char variable? For example "Billys".

  2. #2
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    If the string literal "Billys" was defined in a function, it would be gone as soon as the function was gone, with a couple of exceptions. If you did something like:

    Code:
    #include <stdio.h>
    #include <string.h>
    
    char *foo(void)
    {
        static char str[10];
        strcpy(str, "Hello");
        return str;
    }
    
    int main(void)
    {
        printf("%s, world!\n", foo());
        return 0;
    }
    you could pass the pointer to the string back, because that storage will stay in effect for as long as your program is executing. That said, I am not sure I would recommend doing it. Perhaps some of the other regulars here would care to comment on the pros and cons of such a construct.

    Your best bet would be to pass in a pointer to an existing array, as well as the size of the array, and then modify that array from the function (i.e., put your string into it). Or you could malloc some memory in your function, get the string into that, and pass the pointer back. If you use malloc, don't forget to free the memory when you are done with it.

  3. #3
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Quote Originally Posted by kermit View Post
    If the string literal "Billys" was defined in a function, it would be gone as soon as the function was gone, with a couple of exceptions.
    Returning string literals is OK. Don't quote me on it, but I think string literals are stored in static memory anyway. At any rate, this compiles cleanly with -ansi -pedantic -Wall on.
    Code:
    #include <stdio.h>
    const char * foo( void )
    {
        printf( "%s is located at %p\n" , "Billys" , ( void* )"Billys" );
        return "Billys";
    }
    int main( void )
    {
        const char *p = foo( );
        printf( "p = %p, %s\n" , ( void* )p , p );
        return 0;
    }

  4. #4
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    [edit] As whiteflags has beaten me to saying: [/edit] Actually, a string literal is one of the few things that can be returned from a function. Since string literals are declared in static memory, code like
    Code:
    return "Hello";
    returns a pointer to data that is still in scope for the caller. But string literals, malloc()'d data, and pointers to static arrays are about the only strings that can be returned from functions.

    Depending on what you are trying to do, you'll probably want to use something like this.
    Code:
    void f1(char *buffer, int size) {
        /* ... */
    }
    
    char *f2(void) {
        char *p = malloc(/* ... */);
        /* ... */
        return p;
    }
    
    void split_name(const char *full_name, char **last_name, char **first_name) {
        /* ... */
        *last_name = malloc(/* ... */);
        /* ... */
    }
    Passing in a buffer is nice if you already know how big the data is going to be. If you're going to malloc() your own buffer of some arbitrary size, it may be simplest to return the new buffer. And if you need to return multiple arrays you might need to switch to char** parameters.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  5. #5
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Having a function that returns a string literal seems completely useless to me and a computational burden, although it is possible. If you know the string you are going to return in advance just use it as it is or put it in some preprocessor command. Having to do two context switches between the calling function to the function returning the string and then back is just a waste of time.
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  6. #6
    Novice
    Join Date
    Jul 2009
    Posts
    568
    Quote Originally Posted by claudiu View Post
    Having a function that returns a string literal seems completely useless to me and a computational burden, although it is possible. If you know the string you are going to return in advance just use it as it is or put it in some preprocessor command. Having to do two context switches between the calling function to the function returning the string and then back is just a waste of time.
    Wouldn't it be useful for handling texts and their translations through a DLL? E.g. call the function with parameter X to get a pointer to text in language Y that is then used to print the string?

  7. #7
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by claudiu View Post
    Having a function that returns a string literal seems completely useless to me and a computational burden, although it is possible. If you know the string you are going to return in advance just use it as it is or put it in some preprocessor command. Having to do two context switches between the calling function to the function returning the string and then back is just a waste of time.
    It is useful if a different literal is returned depending on argument.

    For example (although I don't advocate this and provide the example for illustrative purposes only)....
    Code:
    enum MethodDown {Fell, Tumbled, Unknown};
    
    char *Who(MethodDown  value)
    {
        switch (value)
        {
             case Fell:  return "Jack";
             case Tumbled: return "Jill";
             default : return (char *) NULL;
         }
    }
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  8. #8
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Quote Originally Posted by grumpy View Post
    It is useful if a different literal is returned depending on argument.

    For example (although I don't advocate this and provide the example for illustrative purposes only)....
    Code:
    enum MethodDown {Fell, Tumbled, Unknown};
    
    char *Who(MethodDown  value)
    {
        switch (value)
        {
             case Fell:  return "Jack";
             case Tumbled: return "Jill";
             default : return (char *) NULL;
         }
    }
    Indeed, I did not think of this use.
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  9. #9
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    If you're going to have many possibilities, it's best to use array.

    Code:
    enum MethodDown {Fell, Tumbled, ... , Unknown};
    
    const char *Who(MethodDown  value)
    {
        static const char *Method_names[ ] = { 
                         "Jack",
                          "Jill",
                           ...      /* many more */
                   };
        if( value >= Fell && value < Unknown )
               return Method_names[value];
        else return NULL;
    }
    But, it's not thread safe. =(
    Unless Method_names is not declared as static.

  10. #10

  11. #11
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by Bayint Naung View Post
    If you're going to have many possibilities, it's best to use array.

    Code:
    enum MethodDown {Fell, Tumbled, ... , Unknown};
    
    const char *Who(MethodDown  value)
    {
        static const char *Method_names[ ] = { 
                         "Jack",
                          "Jill",
                           ...      /* many more */
                   };
        if( value >= Fell && value < Unknown )
               return Method_names[value];
        else return NULL;
    }
    But, it's not thread safe. =(
    Unless Method_names is not declared as static.
    Not true. That's perfectly threadsafe as-is. Nothing is ever modifying anything in that snippet, and multiple threads are free to use any of the pointers to those string literals simultaneously.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  2. Alegro closes out on me
    By campsoup1988 in forum C++ Programming
    Replies: 8
    Last Post: 04-03-2006, 10:40 AM
  3. <Gulp>
    By kryptkat in forum Windows Programming
    Replies: 7
    Last Post: 01-14-2006, 01:03 PM
  4. How do i un-SHA1 hash something..
    By willc0de4food in forum C Programming
    Replies: 4
    Last Post: 09-14-2005, 05:59 AM
  5. simulate Grep command in Unix using C
    By laxmi in forum C Programming
    Replies: 6
    Last Post: 05-10-2002, 04:10 PM