Macro - combination between function and multiplication


I have the following function (bool is just a #define bool int macro):

bool v2dAngleRad(Vector2D* v2d1, Vector2D* v2d2, double* angle);

It returns the angle between two 2D vectors (the result is stored in angle). I have decided to use a return "boolean" value for my functions which will be used to check if the operation has been successful and only if it's true (in my case #define true 1 ;)) the passed argument(s) will be checked what they contain. I was more or less forced to do that due to the possibility of some operations failing and since there are no exceptions in C as far as I know this seems to be the best way to tackle the situation. In v2dAngleRad(...) the only thing that can go wrong is if an invalid reference to v2d1 and/or v2d2 is passed in which case I want to return false.

In addition to that I wanted to use a macro (just to refresh my memory but also to probably do stuff later on with other functions) to handle the conversion to degrees. I want to define the following macro:

#define v2dAngleDeg(v2d1, v2d2, angle) ... // angle*180./M_PI

The problem is that due to the way my function is defined (with a return value and the argument passed as a pointer to it) I am unable to figure out a way how to use angle in the macro definition to convert it to degrees after it has been populated by the function call. Additional check on the boolean return value also should be made and the conversion has to take place ONLY if the operation has been successful.

If my function was like this

double v2dAngleRad(Vector2D* v2d1, Vector2D* v2d2);

that is returning the angle I would have been able to do

#define v2dAngleDeg(v2d1, v2d2) (v2dAngleRad(v2d1, v2d2)*(180.0/M_PI))

I know this might seem pretty stupid and I'm actually probably going to write a separate function for this but still I would like to know how to handle such a function in general (doesn't matter if I handle angles or tomatoes).

Show source
| function   | C   | macros   | return-value   2016-10-17 01:10 1 Answers

Answers ( 1 )

  1. 2016-10-17 01:10

    If the implementation of the function is simple it is probably easier to just make a v2dAngleRad function that doesn't refer to v2dAngleDeg. But if you do want to delegate, you can use an inline function:

    static inline bool v2dAngleRad(Vector2D* v2d1, Vector2D* v2d2, double* angle)
        if ( ! v2dAngleDeg(v2d1, v2d2, angle) )
             return false;
        *angle *= 180/M_PI;
        return true;

    It would be possible to use a multi-line preprocessor macro instead, however that is less robust. See this thread for comparison of the two approaches.

    Since C99 inline is part of the language, but even on a C89 compiler, most of them have some sort of support for an inline-equivalent keyword or attribute. Of course you don't have to make it an inline function, you could put a non-inline declaration in the header and put this definition in a source file somewhere.

    NB. Consider using the standard #include <stdbool.h> instead of rolling your own bool. Using int to hack a bool can lead to subtle bugs.

◀ Go back