Home > Mobile >  Why am i getting a "lvalue required as unary & operand" error?
Why am i getting a "lvalue required as unary & operand" error?

Time:01-01

I'm working on a function that inserts a value in a binary search tree, i wrote this code:

// this is my decalarations if its relevent
typedef struct element* tree;

typedef struct element
{  
    type data;
    tree right;
    tree left;
}noed;

tree rightSon(tree head)
{
    return (head->right);
}

void insert(tree* a,int val)
{
      
     if(!empty(*a))
     {
         if((*a)->data>val)
         {    
             if(!empty(leftSon(*a)))
                  insert(&leftSon(*a),val); // error here leftson return a tree
            else 
            {
             (*a)->left=newNoed(val);
            
            }
             
         }
         else if((*a)->data<val)
         {
              if(!empty(rightSon(*a)))
                  insert(&rightSon(*a),val); //same error here
            else 
             (*a)->right=newNoed(val);
         }
         else printf("value already exist!\n");
    }
    else
    {
        *a=newNoed(val);
    }
}

i solved the problem by declaring local variables of type tree then assigning the values to them like this:

tree lson;
lson=leftson(*a);
insert(&lson,val);

But i still don't get what was the problem in the first place.

CodePudding user response:

It seems the function leftSon (and rightSon) has the return type tree. That is it returns a temporary object. You may not apply the operator & to a temporary object like in this statement

insert(&leftSon(*a),val);

You could write the code without calling the functions leftSon or rightSon like

 if(!empty(rightSon(*a)))
     insert( &(*a)->right ,val);

In fact the if-else statements like this

         if(!empty(leftSon(*a)))
              insert(&leftSon(*a),val); // error here leftson return a tree
        else 
        {
         (*a)->left=newNoed(val);
        
        }

are redundant. Instead of them you could just write

insert( &(*a)->left, val );

and

insert( &(*a)->right, val );

CodePudding user response:

Your rightSon function is returning the value of the pointer object stored at head->right. You can't take the address of a value.

What you want to do instead is have rightSon return the address of head->right which can then be passed directly to insert.

So change rightSon to return the address:

tree *rightSon(tree head)
{
    return &head->right;
}

And call it like this:

insert(rightSon(*a),val); 

leftSon presumably has the same issue, so make a similar change for that.

Also, hiding a pointer behind a typedef is considered bad practice as it's no longer obvious by just looking at the code that a variable of that type is a pointer and can cause confusion to the reader.

  •  Tags:  
  • c
  • Related