Thread: Can a function appear as an lvalue in C?

  1. #1
    Registered User Dave Jay's Avatar
    Join Date
    Mar 2002
    Posts
    33

    Can a function appear as an lvalue in C?

    I know it can in C++ returning a reference variable. Thanks

  2. #2
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Is there a reason you haven't just tried?
    Code:
    itsme@dreams:~/C$ cat funclval.c
    #include <stdio.h>
    
    int *func(int *num)
    {
      return num;
    }
    
    int main(void)
    {
      int a;
    
      *func(&a) = 5;
      printf("%d\n", a);
    
      return 0;
    }
    itsme@dreams:~/C$ gcc -Wall funclval.c -o funclval
    itsme@dreams:~/C$ ./funclval
    5
    itsme@dreams:~/C$
    Last edited by itsme86; 03-24-2005 at 07:09 PM.
    If you understand what you're doing, you're not learning anything.

  3. #3
    Registered User Dave Jay's Avatar
    Join Date
    Mar 2002
    Posts
    33

    yes

    i messed up the syntax. Thanks chief.

  4. #4
    Registered User Dave Jay's Avatar
    Join Date
    Mar 2002
    Posts
    33

    wait, now i dont understand it

    if "func" in your example returns an address of an integer, a constant value, say it's a 32 bit address 0x0030FFEE, then why does the dereferencing operator * work with that returned value? I thought it was only legal to dereference a pointer variable.
    For example, you couldn't explicitly assign variable "a" like this:

    *0x0030FFEE = 5;

    or like this:

    Code:
    #include <stdio.h>
    
    int main(void)
    {
      int a_address, a = 5;   
    
      a_address = (int) &a;
    
      *a_address = 10;                      /* invalid indirection */
     
      printf("value of a = %d\n", a);  /* attempt to display a with 10 */
    
      return 0;
    }

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Of course it's an invalid indirection. You don't dereference anything that isn't a pointer, so why should that work?

    Quzah.
    Hope is the first step on the road to disappointment.

  6. #6
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Code:
    #include <stdio.h>
    int main(void)
    {
      int *a_address, a = 5;   
      a_address = &a;
      *a_address = 10;
      printf("value of *a_address = %d\n", *a_address);
      return 0;
    }
    [edit]But [wrt topic title]...
    An lvalue is an expression with an object type or an incomplete type other than void
    So no.
    Last edited by Dave_Sinkula; 03-24-2005 at 10:37 PM.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  7. #7
    Registered User Dave Jay's Avatar
    Join Date
    Mar 2002
    Posts
    33

    You guys aren't following me

    consider this definition:

    Code:
    int *func(int *num)
    {
      return num;
    }

    what does func return?
    1.) a constant address
    or
    2.) a variable storing a constant address


    consider this definition:

    Code:
    int func2(int num)
    {
      return num;
    }
    what does func2 return?
    1.) a constant integer
    or
    2.) a variable storing a constant integer


    the call func2(5) returns the integer constant 5, not a variable holding integer 5. Therefore, func(5) cannot be used on the left side of an assignment, say func(5) = 10, which would evaluate to 5 = 10, which is incorrect syntax.

    It's to my understanding that the call func(&a) in the first example will return the constant addresss of a, not a variable holding the constant address of a, so you can't use it in left side assignment, nor dereference a constant object. I don't know if I can elaborate this any further.

    I was stranded on a tropical island for over 2 years, so I am not up to par with this stuff. Perhaps a precise definition of the dereferencing operator may help, but I have yet to see any C text to give one. Thanks fellas.

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by Dave Jay
    consider this definition:

    Code:
    int *func(int *num)
    {
      return num;
    }
    Pointers store addresses. You're returning a pointer, therefore, you're returning an address. Which is, in reality, just another value.

    Quote Originally Posted by Dave Jay
    Code:
    int func2(int num)
    {
      return num;
    }
    It returns a value, just like every other function you write.

    The reason you can't use functions as an lvalue is because an lvalue is something you assign to. You cannot assign a value to the returned value of a function. Functions always return values. Every variable of any kind stores some kind of a value.

    Now, you can use a function to return a pointer, dereference that pointer to get a variable, and assign something to that, but you still can't just assign directly to a function as an lvalue.
    Code:
    int *foo( ) { ... }
    
    *foo( ) = 20;
    But again, you're not assigning to a function, so no, functions cannot be lvalues. Just like the number 20 cannot be an lvalue.

    Quzah.
    Hope is the first step on the road to disappointment.

  9. #9
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    I was stranded on a tropical island for over 2 years, so I am not up to par with this stuff.
    Something similar happened to Arnold in Twins and he turned out to be a genius!
    If you understand what you're doing, you're not learning anything.

  10. #10
    Registered User Dave Jay's Avatar
    Join Date
    Mar 2002
    Posts
    33

    I think I understand it

    this is what has been confusing me but I have, I think, figured out my problem. The semantics of words have confused me a bit too. PLease feel free to correct me if I am wrong.

    First, the actual word "pointer" can refer or mean:
    a) an address (ex. the function takes three pointers as arguments) You pass an argument in C via value, not variable, and the value in this case is a constant address, or pointer.

    b) a variable that stores an address of a specific type
    (ex. declared a pointer of type char) Here the word pointer is referred to as the variable that can hold a constant address, or pointer.

    The two have subtle, yet important distinctions.

    In a similar manner, the word "integer" can refer the literal
    mathematical constant (ex. 5) or an actual variable that stores
    such a constant. The word is interchangably used without any thought.


    Code:
    int *foo( ) { ... }
    
    *foo( ) = 20;
    In this example above, foo returns a pointer of type int, or an address of type int (definition a above), not an actual variable (definition b).
    Let's say for example foo returns the 16 bit address 0x0FFE.
    It would not return a pointer variable containing 0x0FFE but simply the constant 0x0FFE, which can be said a pointer.

    so the statement
    *foo( ) = 20;
    is essentially eqivalent to
    *0x0FFE = 20;

    in this example. However, explictly typing this the 2nd way is not allowed (at least my compiler doesn't allow it). This confused me because the deferencing operator only allows pointer variables as their operands, not pointer constants, yet the first way is allowed and the second way isn't. So, the way I see it, it's just syntax restriction in the C language.

  11. #11
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    You can dereference expressions which yield a pointer type (except for void pointers). You can not dereference an integer expression.

    The expression 0x0FFE yields an integer type and can not be dereferenced. You can use a cast to create an expression that yields a pointer type:
    Code:
    *((int *) 0x0FFE) = 20;
    So, in conclusion: An expression that yields a non-void pointer type may be dereferenced (assuming it points somewhere valid).

  12. #12
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You can still dereference it even if it's not pointing some place valid. It's just not wise to do so.

    Quzah.
    Hope is the first step on the road to disappointment.

  13. #13
    Registered User Dave Jay's Avatar
    Join Date
    Mar 2002
    Posts
    33

    Now I see it

    "The expression 0x0FFE yields an integer type and can not be dereferenced. You can use a cast to create an expression that yields a pointer type"



    This clears things up a lot.

    Thanks guys

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. In over my head
    By Shelnutt2 in forum C Programming
    Replies: 1
    Last Post: 07-08-2008, 06:54 PM
  2. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  3. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  4. <Gulp>
    By kryptkat in forum Windows Programming
    Replies: 7
    Last Post: 01-14-2006, 01:03 PM
  5. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM