QuadrupleA
QuadrupleA

Reputation: 906

C++ method with variable arguments (...) reporting incorrect arg values

I'm having trouble getting variable arguments to pass properly to a method - the method is intended to select a random value within a weighted distribution and return the index of the selected result.

An example usage would be:

int pickupType = randomManager->ByWeights( 3, 0.60f, 0.20f, 0.20f );
switch( pickupType ) {
    // ... pickupType should be 0 to 2, which we can then branch on
}

The function is defined as follows:

#include <cstdarg>

int RandomManager::ByWeights( int weightCount, ... ) {

    va_list argList;

    // Get the total of all weights
    va_start( argList, weightCount );
    float weightTotal = 0;
    for ( int i = 0; i < weightCount; i++ ) {
        weightTotal += va_arg( argList, float );
    }
    va_end( argList );

    // Roll a number in that range
    // ... (further processing - problem occurs above)
}

When I run it in the debugger, the call to va_arg( argList, float ) is returning garbage values ( 2.0, 1.77499998, -1.08420217e-019 ), rather than the values passed in ( 0.60f, 0.20f, 0.20f ).

Any ideas what I'm doing wrong? As far as I can tell I'm following the spec exactly. I've been using http://www.cplusplus.com/reference/cstdarg/ as a reference.

Upvotes: 1

Views: 231

Answers (3)

aaronman
aaronman

Reputation: 18751

If you are using c++ this is not really the correct way to do things anymore. Variadic templates are better than variable args (which are from c). Heres a better example of a variadic sum I did for class a while ago.

#include <iostream>

namespace cs540 {
    template <typename T>
    const T & sum(const T & v) {
        return v;
    }

    template <typename T, typename T2, typename ... Ts>
    T sum(const T & v, const T2 & w, const Ts & ... params) {
        return sum(w+v,params...);
    }
}

int main() {
    using namespace cs540;
    using namespace std;
    cout << sum(1.1,2,3,4,6,8,9,1.1) << endl;
}

Variadic templates are types safe and produce more readable error free code imo.

Upvotes: 0

stardust
stardust

Reputation: 5998

The problem is float is promoted to double when it is passed through ...

so your loop should be

for ( int i = 0; i < weightCount; i++ ) {
    weightTotal += va_arg( argList, double );
}

Upvotes: 1

john
john

Reputation: 87997

In a variadic function, float parameters will be converted to doubles. Try

weightTotal += va_arg( argList, double );

Upvotes: 4

Related Questions