For example, pow() takes double, float or long double arguments in C99. When overloading functions are not supported, how can this be implemented in a simple way?
Asked
Active
Viewed 265 times
-1
-
There is [one function per argument type](http://port70.net/~nsz/c/c11/n1570.html#7.12.7.4). Where do you see overloaded functions? – too honest for this site Sep 06 '15 at 21:33
-
You're mistaking, `pow` takes two double arguments. – Blindy Sep 06 '15 at 21:34
-
If I understood the question, in the case of `pow`, `int` and similar are accepted using implicit conversions. – rpsml Sep 06 '15 at 21:36
-
@rpsml: I do not think so. a `long double` argument to `pow` should generate a compiler warning. – too honest for this site Sep 06 '15 at 21:37
-
@Olaf Yes, it should (depending on the flags) but it also compiles. And, if the long double is in a compatible numerical range, the code produces correct results. Not that I condone this practice. I am just stating the results. – rpsml Sep 06 '15 at 21:45
-
@rpsml: The most important addition for the next release of the standard should be to enforce at least all common warnings by default.. If necessary, with allowance to disable selectively. – too honest for this site Sep 06 '15 at 21:54
-
As mentioned, pow takes doubles as arguments and returns a double. In the case of Microsoft compilers, long double is treated as double, except for the old 16 bit compilers (those use an 80 bit long double). – rcgldr Sep 06 '15 at 22:10
-
Not sure why this is downvoted, it is a good question and the answer is not obvious. – M.M Sep 07 '15 at 01:26
-
@Olaf see 7.25 in C11 for the "overloaded" macros – M.M Sep 07 '15 at 01:28
-
Why did you tag this as C89 when it is a question about C99 ? – M.M Sep 07 '15 at 01:30
-
@M.M: Well, these are not overloaded (I assume that's why you put that into quotation marks), but they use the C11 `_Generic` feature. But this requires to know all types in the macro. Also OP is clearly talking about C99 and the type-generic macros are in `tgmath.h`, not `math.h` as claimed. – too honest for this site Sep 07 '15 at 11:08
-
@Olaf The type-generic macros are in C99 (so they cannot rely on _Generic - or at least, they could not rely on it before C11) – M.M Sep 08 '15 at 02:42
-
@M.M: Oh, I just had a look into the current standard and as that is a perfect application for `_Generic` I was sure came with C11, as that is not possible in C99. A peek into the headers (Linux/gcc/glibc) proves me right:gcc builtins are used. Yet OP still did not clarify he is asking about `tgmath.h` – too honest for this site Sep 08 '15 at 09:31
2 Answers
3
By using a different name for each function, eg
float powf(float base, float exponent);
double pow(double base, double exponent);
long double powl(long double base, long double exponent);
In addition to this, type-generic math (<tgmath.h>
, §7.25 in C11 and §7.22 in C99) defines some macros which do the dirty work without the need of function overloading. You can check this link from this answer to see the internals, but basically it reduces to checks like
sizeof (X) == sizeof (__real__ (X))
or
(__typeof__ (X))1.1 == 1
The example taken from the standard:
EXAMPLE With the declarations
#include <tgmath.h>
int n;
float f;
double d;
long double ld;
float complex fc;
double complex dc;
long double complex ldc;
exp(n) invokes exp(n) (function)
acosh(f) invokes acoshf(f)
sin(f) invokes sin(d) (function)
atan(ld) invokes atanl(ld)
// and so on
-
Note that `
` actually requires compiler magic to implement in C99. Since C11 `_Generic` was added which is capable of implementing the tgmath requirements. – M.M Sep 07 '15 at 01:27 -
`sizeof` is insufficient to detect the type. It might contain padding bytes, thus yield the same value e.g. for `double` and `long double` (they can have the representation, btw.). `__typeof__`, etc. are compiler extensions. – too honest for this site Sep 08 '15 at 09:35
0
With the below, the various types are "actual arguments"
// declaration
double pow(double a, double b);
/// usage
pow(2.0, 3.0);
pow(2.0f, 3.0f);
pow(2.0L, 3.0L);
pow(2, 3);
In each case, the language itself converts these actual arguments to the formal parameters of the function. In this case, to double
.
So one one function pow()
, no overloading.
Other similar yet different functions exist that take other parameters
float powf(float a, float b);

chux - Reinstate Monica
- 143,097
- 13
- 135
- 256