Home > Enterprise >  Why passing `printf` as template function argument succeeds but `cos` failed (msvc 19)?
Why passing `printf` as template function argument succeeds but `cos` failed (msvc 19)?

Time:11-13

I am playing with online c compilers a little bit on link. But the code snippet below got failed when compiled with msvc v19.latest.

#include <iostream>
#include <cmath>
#include <cstdio>

template<class F, class...L>
void test(F f, L...args) {
    std::cout<< "res = " << f(args...) << '\n';
}


int main() 
{
    test(cos, 0.1);   #1
    test(printf, "%s", "aaa");   #2
}

How could it be that line #2 is ok and line #1 can't get a pass?

MSVC is happy with the following code but this time it's GCC's turn to reject it. MSVC's iostream file includes cmath header and GCC #undefs cos :)

#include <stdio.h>
#include <math.h>
//#include <iostream>

template<class F, class...L>
void test(F f, L...args) {
    f(args...);
}

int main() 
{
    test(cos, 0.1);
    test(printf, "%s", "aaa");
}

Since c 20, there's another issue raised in the second answer and has been addressed in this question link

CodePudding user response:

It is failing because cos is an overloaded function in msvc. This means that there are at least 3 different versions of cos:

float cos(float arg);
double cos(double arg);
long double cos(long double arg);

The compiler has no way of guessing which one you are trying to use, but you can give it a hand by using static_cast like the following:

int main()
{
    test(static_cast<double(*)(double)>(cos), 0.1);
    test(printf, "%s", "aaa");   
}

CodePudding user response:

It is not allowed to take an address of a library function (with a few exceptions), and thus to pass it as an argument to another function. Any attempt to do so is unspecified behaviour. MSVC is right to reject your program, and gcc is also right to accept it (and perhaps format your hard disk and send nasty emails to your boss).

  • Related