'Undefined reference' linking errors

bearophile bearophileHUGS at lycos.com
Wed Apr 7 14:10:06 PDT 2010


Few notes:
- opCall() of AvgWeighted was abstract.
- keep in mind that in D classes are CamelCase;
- variable names are written like weightSum (but once in a while a underscore doesn't kill).
- Be careful because ref arguments are tricky.
- There is a line like foreach (r; reputationUser) r = 1; that can be a bug.
- foreach (objectID, rating; reputationObject) rating /= weightSum[objectID]; can be another bug.
- Use better attribute names in Rating struct, when you need to comment a variable name then it's often a wrong name.
- To create structs you can most times use the syntax I've used in the main.
- In methods/functions divide your code into paragraphs;
- keep your indentations more coherent
- I suggest to add contracts and unittests.

Keeping the code tidy helps a lot avoid bugs. The following is surely not perfect, but it's better:


struct Rating {
    uint userID, objectID;
    double rating;
}


class Reputation {
    this() {}

    this(ref Rating[] ratings,
         ref double[] reputationUser,
         ref double[] reputationObject) {}
}


class AvgWeighted : Reputation {
    double[] weightSum;

    this(ref Rating[] ratings,
         ref double[] reputationUser,
         ref double[] reputationObject) {
        weightSum.length = reputationObject.length;

        foreach (r; ratings) {
            reputationObject[r.objectID] += r.rating;
            weightSum[r.objectID] += reputationUser[r.userID];
        }

        foreach (objectID, rating; reputationObject)
            rating /= weightSum[objectID]; // useless?
    }

    void opCall(ref Rating[] ratings,
                ref double[] reputationUser,
                ref double[] reputationObject) {}
}


class AvgArithmetic : AvgWeighted {
    this(ref Rating[] ratings,
         ref double[] reputationUser,
         ref double[] reputationObject) {
        // foreach (r; reputationUser) r = 1; // bug?
        reputationUser[] = 1;
        super(ratings, reputationUser, reputationObject);
    }

    void something(ref Rating[] ratings,
                   ref double[] reputationUser,
                   ref double[] reputationObject) {
        AvgWeighted(ratings, reputationUser, reputationObject);
    }
}


void main() {
    double[] reputationUser;
    reputationUser.length = 999;

    double[] reputationObject;
    reputationObject.length = 1;

    Rating[] r;
    foreach (userID; 0 .. reputationUser.length)
        r ~= Rating(userID, 0, userID % 3);
}


Bye,
bearophile


More information about the Digitalmars-d-learn mailing list