Compile-time introspection of free-floating functions, does this work?

J

Juha Nieminen

I think I might have come up with a way to detect at runtime if a
free-floating function has been defined or not, and avoid referencing
it if it isn't. More concretely, in a project of mine I need to know
if std::strtold exists in <cstdlib> or not, and call it only if it does
(and if it doesn't, fall back to calling std::strtod).

What's the jury's opinion of this? Standard, non-standard, ill-formed,
suspicious? Any suggestions to make it better?

//---------------------------------------------------------------------
#include <iostream>
#include <cstdlib>

namespace std
{
template<typename T1, typename T2>
char strtold(T1, T2);
}

namespace
{
const bool hasStrtold =
(sizeof(std::strtold("0", (char**)0)) > 1);

template<bool> struct Func;

template<> struct Func<false>
{
static void func() { std::cout << "No strtold().\n"; }
};

template<> struct Func<true>
{
static void func()
{
std::cout << "Has strtold(). Test: "
<< std::strtold("12.3", (char**)0) << "\n";
}
};

void func()
{
Func<hasStrtold>::func();
}
}

int main()
{
func();
}
//---------------------------------------------------------------------
 
V

Victor Bazarov

I think I might have come up with a way to detect at runtime if a
free-floating function has been defined or not, and avoid referencing
it if it isn't. More concretely, in a project of mine I need to know
if std::strtold exists in<cstdlib> or not, and call it only if it does
(and if it doesn't, fall back to calling std::strtod).

What's the jury's opinion of this? Standard, non-standard, ill-formed,
suspicious? Any suggestions to make it better?

//---------------------------------------------------------------------
#include<iostream>
#include<cstdlib>

namespace std
{
template<typename T1, typename T2>
char strtold(T1, T2);
}

namespace
{
const bool hasStrtold =
(sizeof(std::strtold("0", (char**)0))> 1);

template<bool> struct Func;

template<> struct Func<false>
{
static void func() { std::cout<< "No strtold().\n"; }
};

template<> struct Func<true>
{
static void func()
{
std::cout<< "Has strtold(). Test:"
<< std::strtold("12.3", (char**)0)<< "\n";
}
};

void func()
{
Func<hasStrtold>::func();
}
}

int main()
{
func();
}
//---------------------------------------------------------------------

So far the only suspicious part in this code is when you define your own
'strtold' template in the 'std' namespace - are you allowed to? I am
not sure what the correct answer is to that.

Another small issue is that the Standard claims that 'strtold' exists.
Are you working to identify a non-compliance in a particular compiler?
I'm asking because a compliant compiler will have 'strtold' defined, I
think, at least according to 21.7/T78. Of course, I may have missed
something there...

V
 
M

Marc

Juha said:
I think I might have come up with a way to detect at runtime if a
free-floating function has been defined or not, and avoid referencing
it if it isn't. More concretely, in a project of mine I need to know
if std::strtold exists in <cstdlib> or not, and call it only if it does
(and if it doesn't, fall back to calling std::strtod).

Just as something to compare against, I wrote something for a similar
purpose here:
http://gcc.gnu.org/ml/gcc/2012-01/msg00048.html

with the added complication that the function to test is in the global
namespace and that I wanted to define the function (hence a likely odr
violation), but the idea should be there.
 
J

Juha Nieminen

Victor Bazarov said:
Another small issue is that the Standard claims that 'strtold' exists.

The C++11 maybe, not the C++98 one. Unfortunately it's a bit too early
to be demanding a C++11-compliant compiler. In a few years maybe.
 
I

Ian Collins

So far the only suspicious part in this code is when you define your own
'strtold' template in the 'std' namespace - are you allowed to? I am
not sure what the correct answer is to that.

I'm pretty sure any function beginning with str is reserved, at least in
the C standard.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top