0
0

Hello. Using Dev-C++ and FModEx 0.4.30.4.
Problem is: I don’t know how to correctly cast unnamed temporary objects.

Error text is:
[quote:1zvzkksp]no matching function for call to `FMOD::System::set3DListenerAttributes(int, const FMOD_VECTOR, const FMOD_VECTOR, const FMOD_VECTOR, const FMOD_VECTOR)’
candidates are: FMOD_RESULT FMOD::System::set3DListenerAttributes(int, const FMOD_VECTOR*, const FMOD_VECTOR*, const FMOD_VECTOR*, const FMOD_VECTOR*) [/quote:1zvzkksp]

My code looks like this:
[code:1zvzkksp]
ERRCHECK(
fsystem->set3DListenerAttributes(
0,
(const FMOD_VECTOR){position._x, position._y, position._z},
(const FMOD_VECTOR){velocity._x, velocity._y, velocity._z},
(const FMOD_VECTOR){forward._x, forward._y, forward._z},
(const FMOD_VECTOR){up._x, up._y, up._z}
)
);[/code:1zvzkksp]

position, velocity, forward and up are of my own Vector class.

Thanks in advance.

  • You must to post comments
0
0

[code:1intadal]
FMOD_VECTOR FMforward = {forward._x, forward._y,forward._z};
FMOD_VECTOR FMup = {up._x, up._y, up._z};
FMOD_VECTOR FMvel = {velocity._x, velocity._y, velocity._z};
FMOD_VECTOR FMpos = {position._x, position._y, position._z};
ERRCHECK(
fsystem->set3DListenerAttributes(
0,
&FMpos,
&FMvel,
&FMforward,
&FMup)
);
[/code:1intadal]

  • You must to post comments
0
0

Indeed that’s how I ended up doing things but I hoped to not have to use variables. I’m on a crazy quest for efficiency. It’s more about pushing the envelope than being truly important.

  • You must to post comments
0
0

[quote:33rgqt8t]Indeed that’s how I ended up doing things but I hoped to not have to use variables. I’m on a crazy quest for efficiency. It’s more about pushing the envelope than being truly important.[/quote:33rgqt8t]
Those variables are going on the stack either way. The issue with your code is your passing the vector by value and the interface requires a pointer. You could possible remedy that by putting an ampersand before it, that is technically valid because the lifetime of that temporary object should be until the outter expression (the function call) is resolved. It’s pretty ugly though.

A trick you can use which will avoid making a temporary at all, is to just cast your vector to an FMOD vector, however here are some caveats:
Your vector type must be exactly 3 floats ordered x, y, z, and contain no other members and have no virtual functions (inherited or otherwise).

[code:33rgqt8t]
ERRCHECK(
fsystem->set3DListenerAttributes(
0,
(FMOD_VECTOR)(&position),
(FMOD_VECTOR
)(&velocity),
(FMOD_VECTOR)(&forward),
(FMOD_VECTOR
)(&up)
)
);[/code:33rgqt8t]

If you go this route, it’s good to have an assert somewhere for safety, something like:
[code:33rgqt8t]assert(sizeof(FMOD_VECTOR) == sizeof(Vector3))[/code:33rgqt8t]

Even better if it is a compile time assertion, something like:
[code:33rgqt8t]BOOST_STATIC_ASSERT( sizeof(FMOD_VECTOR) == sizeof(Vector3) );[/code:33rgqt8t]

  • You must to post comments
0
0

Unfortunately I can’t cast my Vectors to FMOD_VECTOR.
And it couldn’t compile by trying to pass the address of the temporary:
[code:1wpv2tw4]// something like
FMOD_System_Set3DListenerAttributes(
fsystem,
0,
(FMOD_VECTOR)(&{position._x, position._y, position._z}),
(FMOD_VECTOR
)(&{velocity._x, velocity._y, velocity._z}),
(FMOD_VECTOR*)(&{forward._x, forward._y, forward._z}),
(FMOD_VECTOR*)(&{up._x, up._y, up._z})
);

// or
FMOD_System_Set3DListenerAttributes(
fsystem,
0,
&(FMOD_VECTOR){position._x, position._y, position._z},
&(FMOD_VECTOR
){velocity._x, velocity._y, velocity._z},
&(FMOD_VECTOR*){forward._x, forward._y, forward._z},
&(FMOD_VECTOR*){up._x, up._y, up._z}
);
[/code:1wpv2tw4]

I think that if the FMOD interface would’ve used passing by reference instead of pointer this would’ve been possible. If I’m wrong, please correct me, because I kind of "invented" the above syntax.

Also MinGW forces me to use the C interface within an otherwise pure C++ project, but that shouldn’t interfere with this right?

  • You must to post comments
0
0

I dont think people have enough sounds in their game to really make it a huge concern. if your structure has the 3 floats at the start of the struct, in theory you should be able to cast it down (casting it through (void*) first). But the result in stack usage and speed should be relatively negligable if not the same.

I too use the c interface in a c++ environment; devc++ then code::blocks (wich I recomend you use). I do use ms for the debugger though. Given the c++ interface is exactly matched with the c one (thank god for that), I see no need to use the c++ interface, even in MSVC. It allows me to change compiler whenver I like.

  • You must to post comments
0
0

Yes, you’re right that the performance difference of making a temporary is negligable in most cases. It’s just an easier way to condense the code for readability.

There should be no issue using the C interface inside a C++ application.

  • You must to post comments
0
0

FWIW if you really want to get the code to work this way the position of the parentheses is critical. You must cast to FMOD_VECTOR then get the address of that not cast to a FMOD_VECTOR*. E.g., testing in the 3d example…

[code:2mtld18t] result = system->set3DListenerAttributes(0,
&listenerpos,
&vel,
&((FMOD_VECTOR){0.0f, 0.0f, 1.0f}),
&((FMOD_VECTOR){0.0f, 1.0f, 0.0f}));[/code:2mtld18t]

  • You must to post comments
0
0

Unfortunately the code below gives the error:
[quote:3bbpasho]non-lvalue unary in `&'[/quote:3bbpasho]

[code:3bbpasho] FMOD_System_Set3DListenerAttributes(
fsystem,
0,
&((FMOD_VECTOR){position._x, position._y, position._z}),
&((FMOD_VECTOR){velocity._x, velocity._y, velocity._z}),
&((FMOD_VECTOR){forward._x, forward._y, forward._z}),
&((FMOD_VECTOR){upward._x, upward._y, upward._z}),
);
[/code:3bbpasho]

  • You must to post comments
0
0

..could be compiler specific then I can’t reproduce that. Although there is an extraneous comma after the ‘up’ vector expression in the code you posted, try:

[code:t8a3hreg] FMOD_System_Set3DListenerAttributes(
fsystem,
0,
&((FMOD_VECTOR){position._x, position._y, position._z}),
&((FMOD_VECTOR){velocity._x, velocity._y, velocity._z}),
&((FMOD_VECTOR){forward._x, forward._y, forward._z}),
&((FMOD_VECTOR){upward._x, upward._y, upward._z})
); [/code:t8a3hreg]

We of course don’t know the structure of your own vector structure.[/code]

  • You must to post comments
0
0

It was indeed compiler specific. Wouldn’t work on old Dev-C++ (GCC 3.4.2) but compiles with warnings (and works) on newer Code::Blocks (GCC 4.4.1). The final EXE is also a couple hundred KBs bigger but that’s for another time, and another forum. Probably has to do with debugging info though?

Anyway thanks.

  • You must to post comments
Showing 10 results
Your Answer

Please first to submit.