Wadwamille
Wadwamille

Reputation: 57

"Expression must be a modifiable LValue"

I am trying to create a physics simulation that simulates physics on all spaghettiObjects and displays those as text. There aren't currently any physics simulation, but those would go where //math is written

I am having trouble with this code. I'm a fairly new programmer and I started in java and am trying to learn c++. The errors are on line 48,49,50 where I'm trying to do the same thing with different method calls. I can't figure out what is wrong here, when I remove the = worldObjectToUpdate.variable it no longer throws an error.

Here is all of the code

#include <iostream>
#include <string>
using namespace std;
//Created to hold the x, y, velocity and mass of an object.  
//It's called a spaghettiObject cause I was bored.
//A better name would probably be something like "worldObject"
struct spaghettiObject {
public:
    float velocity;
    float positionX;
    float positionY;
    float mass;
};
//All world objects in an array
spaghettiObject myArray[5];
//test zone
spaghettiObject test;
spaghettiObject createTestObject() {
    myArray[1] = test;
    test.mass = 2;
    test.positionX = 2;
    test.positionY = 2;
    test.velocity = 2;
    return test;
}
//Output from the physics simulation to the render function
spaghettiObject output;
//Calculates the position of a spaghettiObject's x using velocity
float nextPositionX(spaghettiObject objectToTransform) {
    float objectToTransformNewX = objectToTransform.positionX;
    //math
    return  objectToTransformNewX;
}
//Calculates the position of a spaghettiObject's x using velocity
float nextPositionY(spaghettiObject objectToTransform) {
    float objectToTransformNewY = objectToTransform.positionY;
    //math
    return objectToTransformNewY;
}
//Calculates the new velocity. for use:after updating x and y of object
float nextVelocity(spaghettiObject objectToUpdate) {
    float objectToUpdateNewV = objectToUpdate.velocity;
    //math
    return objectToUpdateNewV;
}
//Designed to be where all of the update functions are called
void updateWorldObject(spaghettiObject worldObjectToUpdate) {
    nextPositionX(worldObjectToUpdate) = worldObjectToUpdate.positionX;
    nextPositionY(worldObjectToUpdate) = worldObjectToUpdate.positionY;
    nextVelocity(worldObjectToUpdate) = worldObjectToUpdate.velocity;
}
//calculates position of variable defined above, myArray
void nextUpdateOfMyArray() {
    //temp object that is effectively the entire array
    spaghettiObject temp;
    //initilization of temp
    temp.mass = 0;
    temp.positionX = 0;
    temp.positionY = 0;
    temp.velocity = 0;
    //for calling functions for
    //each of the objects
    for (int i = 0; i++; i < (sizeof myArray / sizeof spaghettiObject)) {       
        //assigning the current object in the array to the temp object
        myArray[i] = temp;
        //Calling the update functions
        updateWorldObject(temp);
        //test
        createTestObject() = temp;
        //regular code
        output = temp;
    }
}
//Used to update the physics
void update() {
    nextUpdateOfMyArray();
}
//Used to render a console output
void render() {
    cout << output.mass + output.positionX + output.positionY + output.velocity;
}
int main() {
    update();
    render();
    cin.get();
}

Upvotes: 1

Views: 9650

Answers (2)

sqykly
sqykly

Reputation: 1586

functionCall() = value in updateWorldObject is your problem. You can't assign a value to a function call. Where are you intending for that value to go? If you want it in the object, the lhs of the assignment should be objectToModify.propertyToModify or pointerToObject->propertyToModify. If you want it in an independent variable, the lhs is variableToModify. If you want it to be an argument to a function, there is no assignment expression. In no case does it make sense to assign to a function call expression.

In this case it appears you are trying to update the properties of the argument worldObjectToUpdate, but that will not work either. The reason is that arguments in c++ are passed by value, so declaring the parameter as a SpaghettiObject tells c++ to copy the whole object onto the call stack - this is not what you are used to in java. That new object will then be modified inside the function, but that object disappears when the function returns. It's like opening a file, making some edits, and closing it without saving.

Instead, you want to declare the parameter as a reference to an object. In java, all objects are references, so you never make that distinction. In c++, there are two syntactic ways to indicate that a parameter is a reference so that the function will modify the object you pass to it instead of cloning it and throwing away the changes.

void function(Object* pointerToObject) {
    pointerToObject->propertyToModify = newValue;
}

Object anObject;
function(&anObject);

In that case, the reference is a pointer. It points to which object you are using. When a pointer is copied onto the stack as an argument, the object itself is not copied, and the function is able to change its properties or call its methods using -> instead of .. You must obtain a pointer to an object with operator & like &anObject.

The other syntactic way to refer to an object is closer to what you use in java.

void function(Object& objectToModify) {
    objectToModify.propertyToModify = newValue;
}

Object anObject;
function(anObject);

The Object& type is a reference to an Object, which is pretty much what you are thinking of coming from java: you still use the . operator, you never do anything special to create the reference, the object is not copied. The downside to a reference (as opposed to a pointer) is that once a reference refers to an object, it can't be reassigned to another object, but as a parameter to a function it will be fine.

Upvotes: 1

macroland
macroland

Reputation: 1025

createTestObject() = temp; most probably will be temp=createTestObject()

Upvotes: 0

Related Questions