What is the preference of function/method/template name resolving in C++? - c++

How does the C++ compiler decide which function/method to call if there are multiple possibilities?
In my specific case I have the standard free function of the C++ Run time and I also have a templated free variant, like this:
// The definitions of the C++ Run Time Library (from memory.h)
extern malloc(size_t s);
extern void free(void *p);
// Our own memory management functions
extern void *OurMalloc(size_t s);
extern void OurFree(void *p);
// Own variants to overrule malloc and free (instead of using #define)
template<typename T>
void *malloc(T t)
{
return OurMalloc(t);
}
template<typename T>
void free(T *t)
{
OurFree(t);
}
I tested this using the following code:
void main(void)
{
void *p = malloc(10);
free(p);
}
If I compile and run this, it seems that the call to malloc is correctly replaced by the templated variant. So far, so good.
However, the call to free is not replaced by the templated variant, and the standard C++ function is still called.
What rules does the C++ compiler use to decide which variant to give priority?
Is this related to the Koenig-lookup rules?
Note: I tried this alternative because using #define does not solve the problem (see question How to use C macro's (#define) to alter calls but not prototypes).

Overload resolution is quite complicated in general.
In your case, it is quite easy: a function template is not considered if there is an exact match. For free it is the case (the standard free takes a void*), for malloc it isn't (the standard malloc takes a size_t, you are passing an int and size_t can't be a typedef for int -- size_t is unsigned). If you call free with a type other than void*, it should instantiate your template.
Running:
#include <iostream>
void* ml(size_t s)
{
std::cout << "ml(size_t)\n";
}
void fr(void *p)
{
std::cout << "fr(void*)\n";
}
template<typename T>
void* ml(T t)
{
std::cout << "ml<" << typeid(T).name() << ">(T)\n";
}
template<typename T>
void fr(T *t)
{
std::cout << "fr<" << typeid(T).name() << ">(T*)\n";
}
int main()
{
void* p1 = ml((size_t)10);
fr(p1);
int* p2 = (int*)ml(10);
fr(p2);
return 0;
}
I get
ml(size_t)
fr(void*)
ml<i>(T)
fr<i>(T*)
and i is what returns typeid(int).name()

For your particular issue about malloc and free, the problem is that in your call to malloc:
void *p = malloc(10);
the parameter 10 is typed as an int, while the signature for the runtime's malloc() calls for an unsigned argument. Since there's not an exact match, the compiler prefers the templated malloc where it can create an exact match.
When you call:
free(p);
the type of p is void* which does exactly match the runtime's signature for free() so the compiler doesn't bother using the templated free.

It is not possible to "replace" the standard malloc using this technique. Other answers have already explained that because you are using a signed value as an argument in malloc call, your templated version happens to "win" over the standard one because the standard one expects an unsigned argument.
To better illustrate this I just wanted to add that if you supply either an unsigned int or unsigned long argument in your malloc call
void *p1 = malloc(10u);
void *p2 = malloc(10ul);
and you'll notice that in one of these calls your templated version of malloc also doesn't "work" anymore and the standard one is called instead, since it is a better match for the argument (provided that on your platform size_t is defined as either unsigned int or unsigned long)

Not answering the question you asked, but what it seems like you're trying to do:
If it's available on your system, you can use LD_PRELOAD to preload a .so library you build that has your versions of malloc and free. Then they will definitely be called instead of the standard versions.

Related

mingw - cdecl required to run functions correctly

The code below is running correctly with any online gcc compiler I found (gcc 9.2.0), it also run correctly with CYGWIN gcc compiler, but unfortunately it doesn't work well with MINGW gcc compiler - looks like it passes invalid parameter as "this" to "methodA" and "methodB" methods, when they are called, instead of expected results (56,58) i get some random high numbers.
#include <iostream>
using namespace std;
class CallbackBase
{
public:
using METHOD_TYPE = int (CallbackBase::*)(...);
};
class CallbackProvider : public CallbackBase
{
public:
int methodA(int a,int b,int c)
{
return a+b+c+d;
}
int methodB(double a,double b,double c)
{
return a+b+c+d;
}
private:
int d=8;
};
class CallbackRunner
{
public:
CallbackBase::METHOD_TYPE m_method;
CallbackBase* m_this;
void install (CallbackBase* _this, CallbackBase::METHOD_TYPE _method)
{
m_method =_method;
m_this =_this;
}
int Run1()
{
return (m_this->*m_method)(15L,16L,17L);
}
int Run2()
{
return (m_this->*m_method)(15.6,16.7,17.8);
}
};
int main()
{
CallbackProvider cp;
CallbackRunner cr;
cr.install(&cp,(CallbackBase::METHOD_TYPE)&CallbackProvider::methodA);
cout << "result " << cr.Run1() << endl;
cr.install(&cp,(CallbackBase::METHOD_TYPE)&CallbackProvider::methodB);
cout << "result " << cr.Run2() << endl;
return 0;
}
The problem is solved if I add __cdecl attribute to this methods:
int __cdecl methodA(int a,int b,int c)
int __cdecl methodB(double a,double b,double c)
I doesn't use -mrtd compilation flag.
According to this, __cdecl should be a default calling convention for gcc compilers but looks like it doesn't the case for MINGW.
Is that possible to set __cdecl as a default calling convention for my project?
or as alternative, is there a way to set "default" attribute to all the methods?
I am using Windows 10 with 64 bit architecture.
You're not allowed to use a pointer to function with a C-style variadic parameter to call functions with regular parameters. There's a reason your cr.install calls don't work without a pointer cast.
The simplest solution is to cast the callback pointer to the proper type before calling it, based on the arguments you want to call it with. You can write a template that will do the cast for you.
However, this is highly unsafe, since it's easy to cast to an incorrect type. (Your code would be equally unsafe, if it wasn't undefined to begin with.)
A safer approach is to store the function pointer in a std::any. Then, attempting a callback call with invalid parameters will cause a runtime error (that is, std::any_cast will detect parameter type mistmatch).
Your code has a bug - it has undefined behavior. The cast from int (Class::*)(int, int, int) to int (CallbackBase::*)(...) triggers it. Those two types are not the same, and you can not cast between them willy-nilly.
This is an extract of your code where you are attempting this illegal cast:
cr.install(&cp,(CallbackBase::METHOD_TYPE)&CallbackProvider::methodA);
You can easily see the diagnostic message yourself if you remove the cast:
error: cannot convert 'int (CallbackProvider::*)(int, int, int)' to 'CallbackBase::METHOD_TYPE' {aka 'int (CallbackBase::*)(...)'}
The fact that it works on some compilers and not on the others is of no significance, it is just a manifestation of undefined behavior.
You could cast back to the original function type before calling it, but than the whole thing would become even more ugly.
Another option might be to make your concrete functions variadic as well, and access parameters via VA_ARGS. This would throw the whole C++ type safety off the window, and I do not like this approach either.
Just for the trivia, it looks like mingw's gcc uses a legacy calling convention (cdecl is indeed quite legacy) for variadic functions, while other compilers would use modern AMD ABI.

Is it safe to convert a template lambda to a `void *`?

I'm working on implementing fibers using coroutines implemented in assembler. The coroutines work by cocall to change stack.
I'd like to expose this in C++ using a higher level interface, as cocall assembly can only handle a single void* argument.
In order to handle template lambdas, I've experimented with converting them to a void* and found that while it compiles and works, I was left wondering if it was safe to do so, assuming ownership semantics of the stack (which are preserved by fibers).
template <typename FunctionT>
struct Coentry
{
static void coentry(void * arg)
{
// Is this safe?
FunctionT * function = reinterpret_cast<FunctionT *>(arg);
(*function)();
}
static void invoke(FunctionT function)
{
coentry(reinterpret_cast<void *>(&function));
}
};
template <typename FunctionT>
void coentry(FunctionT function)
{
Coentry<FunctionT>::invoke(function);
}
int main(int argc, const char * argv[]) {
auto f = [&]{
std::cerr << "Hello World!" << std::endl;
};
coentry(f);
}
Is this safe and additionally, is it efficient? By converting to a void* am I forcing the compiler to choose a less efficient representation?
Additionally, by invoking coentry(void*) on a different stack, but the original invoke(FunctionT) has returned, is there a chance that the stack might be invalid to resume? (would be similar to, say invoking within a std::thread I guess).
Everything done above is defined behaviour. The only performance hit is that inlining something aliased thro7gh a void pointer could be slightly harder.
However, the lambda is an actual value, and if stored in automatic storage only lasts as long as the stored-in stack frame does.
You can fix this a number of ways. std::function is one, another is to store the lambda in a shared_ptr<void> or unique_ptr<void, void(*)(void*)>. If you do not need type erasure, you can even store the lambda in a struct with deduced type.
The first two are easy. The third;
template <typename FunctionT>
struct Coentry {
FunctionT f;
static void coentry(void * arg)
{
auto* self = reinterpret_cast<Coentry*>(arg);
(self->f)();
}
Coentry(FunctionT fin):f(sts::move(fin)){}
};
template<class FunctionT>
Coentry<FunctionT> make_coentry( FunctionT f ){ return {std::move(f)}; }
now keep your Coentry around long enough until the task completes.
The details of how you manage lifetime depend on the structure of the rest of your problem.

Is there a use for function declarations inside functions?

We can declare functions inside functions (I wanted a local variable, but it parses as a function declaration):
struct bvalue;
struct bdict {
bdict(bvalue);
}
struct bvalue {
explict operator bdict() const;
}
struct metainfo {
metainfo(bdict);
}
void foo(bvalue v) {
metainfo mi(bdict(v)); // parses as function declaration
metainfo mi = bdict(v); // workaround
// (this workaround doesn't work in the presence of explicit ctors)
}
Are the sole reasons "because it makes the parser simpler" and "because the standard says so", or is there an obscure use for this?
This is really a C question, because this behaviour was inherited directly from C (although it gets much more press in C++ because of the most vexing parse).
I suspect the answer (in the context of C, at least) is that this allows you to scope the existence of your function declarations to precisely where they're needed. Maybe that was useful in the early days of C. I doubt anyone does that any more, but for the sake of backward compatibility it can't be removed from the language.
It's useful if you need to use an external function whose name would conflict with an internal (static) function or variable in the current translation unit (source file). For instance (silly but it gets the point across):
static int read(int x)
{
return bar(x);
}
static int foo()
{
ssize_t read(int, void *, size_t);
read(0, buf, 1);
}
A function declaration inside another function hides other overloaded functions. e.g. Compiler error on Line 7
#include <iostream>
void f(int);
int main() {
void f(char *);
f(10); // Line 7
f("Hello world");
return 0;
}
void f(int a) {
std::cout << a;
}
void f(char *str) {
std::cout << str;
}
Are the sole reasons "because it makes
the parser simpler" and "because the
standard says so"
Yea, basically.
Everything that can be a function declaration, is a function declaration.
Unfortunately it's one of those "just is" cases.

a "general function signature" pointer that points to an arbitrary function

I'll try to explain better what I want to do.
I read a file with function signatures, and I want to create a pointer to each function.
For example, a file that looks like this:
something.dll;int f(char* x, int y, SOMESTRUCT z)
something.dll;void g(void)
something.dll;SOMESTRUCT l(longlong w)
now, during runtime I want be able to create pointers to these functions (by loading something.dll and using GetProcAddress to these functions).
Now, GetProcAddress returns FARPROC which points to an arbitrary functions, but how can I use FARPROC to call these functions during runtime?
From what I know, I need to cast FARPROC to the correct signature, but I can't do it during runtime (or at least I don't know how).
Does anyone have any idea how to design do that?
Thanks! :-)
Function types are compile-time in C++, so it won't work, unless you can define all the types you're going to use in advance.
Its a matter of pushing the arguments to the stack (and local vars are like that) and calling the function as void (__cdecl *)(void).
With some other kinds of functions (like fastcall, or thiscall) it can be more problematic.
Update: I actually made an example, and it works on codepad:
(Also works with stdcall functions, because of stack restore after aligned stack alloc)
http://codepad.org/0cf0YFRH
#include <stdio.h>
#ifdef __GNUC__
#define NOINLINE __attribute__((noinline))
#define ALIGN(n) __attribute__((aligned(n)))
#else
#define NOINLINE __declspec(noinline)
#define ALIGN(n) __declspec(align(n))
#endif
//#define __cdecl
// Have to be declared __cdecl when its available,
// because some args may be passed in registers otherwise (optimization!)
void __cdecl test( int a, void* b ) {
printf( "a=%08X b=%08X\n", a, unsigned(b) );
}
// actual pointer type to use for function calls
typedef int (__cdecl *pfunc)( void );
// wrapper type to get around codepad's "ISO C++" ideas and gcc being too smart
union funcwrap {
volatile void* y;
volatile pfunc f;
void (__cdecl *z)(int, void*);
};
// gcc optimization workaround - can't allow it to know the value at compile time
volatile void* tmp = (void*)printf("\n");
volatile funcwrap x;
int r;
// noinline function to force the compiler to allocate stuff
// on stack just before the function call
NOINLINE
void call(void) {
// force the runtime stack pointer calculation
// (compiler can't align a function stack in compile time)
// otherwise, again, it gets optimized too hard
// the number of arguments; can be probably done with alloca()
ALIGN(32) volatile int a[2];
a[0] = 1; a[1] = 2; // set the argument values
tmp = a; // tell compiler to not optimize away the array
r = x.f(); // call the function; returned value is passed in a register
// this function can't use any other local vars, because
// compiler might mess up the order
}
int main( void ) {
// again, weird stuff to confuse compiler, so that it won't discard stuff
x.z = test; tmp=x.y; x.y=tmp;
// call the function via "test" pointer
call();
// print the return value (although it didn't have one)
printf( "r=%i\n", r );
}
Once you have a FARPROC, you can cast the FARPROC into a pointer to the appropriate function type. For example, you could say
int (*fPtr)(char*, int, SOMESTRUCT) = (int (*)(char*, int, SOMESTRUCT))GetProcAddress("f");
Or, if you want to use typedefs to make this easier:
typedef int (*FType)(char *, int, SOMESTRUCT);
FType fPtr = (FType)GetProcAddress("f");
Now that you have the function pointer stored in a function pointer of the appropriate type, you can call f by writing
fPtr("My string!", 137, someStructInstance);
Hope this helps!
The compiler needs to know the exact function signature in order to create the proper setup and teardown for the call. There's no easy way to fake it - every signature you read from the file will need a corresponding compile-time signature to match against.
You might be able to do what you want with intimate knowledge of your compiler and some assembler, but I'd recommend against it.

Stringify template arguments

Is it possible in C++ to stringify template arguments?
I tried this:
#include <iostream>
#define STRINGIFY(x) #x
template <typename T>
struct Stringify
{
Stringify()
{
std::cout << STRINGIFY(T) << endl;
}
};
int main()
{
Stringify<int> s;
}
But what I get is a T, and not an int. Seems that the preprocessor macros are evaluated before template instantiation.
Is there any other way to do this?
Is there any way for the preprocessing to take place after template instantiation? (Compiler is VC++).
You could try
typeid(T).name()
Edit: Fixed based on comments.
You could use some template magic.
#include <iostream>
template <typename T>
struct TypeName { static const char *name; };
template <typename T>
const char *TypeName<T>::name = "unknown";
template <>
const char *TypeName<int>::name = "int";
template <typename T>
struct Stringify
{
Stringify()
{
std::cout << TypeName<T>::name << std::endl;
}
};
int main()
{
Stringify<int> s;
}
This has an advantage over RTTI (i.e. typeinfo) - it is resolved during compilation; and disadvantage - you need to provide type information yourself (unless there is some library that does that already that I'm not aware of; maybe something in Boost even).
Or, as Martin York suggested in comments, use inline function templates instead:
template <typename T>
inline const char* typeName(void) { return "unknown"; }
template <>
inline const char* typeName<int>(void) { return "int"; }
// ...
std::cout << typeName<T>() << std::endl;
But, if you'll ever need to store more information about that particular type, then class templates will probably be better.
Your code doesn't work because the preprocessor, responsible for searching and expanding the macros you use in your code, is not aware of the language itself. It is just a text parser. It finds that STRINGIFY(T) in the very function template and expand it, much before you give a type to that template. As it turns out, you will always get "T" instead of the typename you expected, unfortunately.
As litb suggested, I've (badly) implemented this `getTypeName' function template that returns the typename you pass it:
#include <iostream>
template <typename _Get_TypeName>
const std::string &getTypeName()
{
static std::string name;
if (name.empty())
{
const char *beginStr = "_Get_TypeName =";
const size_t beginStrLen = 15; // Yes, I know...
// But isn't it better than strlen()?
size_t begin,length;
name = __PRETTY_FUNCTION__;
begin = name.find(beginStr) + beginStrLen + 1;
length = name.find("]",begin) - begin;
name = name.substr(begin,length);
}
return name;
}
int main()
{
typedef void (*T)(int,int);
// Using getTypeName()
std::cout << getTypeName<float>() << '\n';
std::cout << getTypeName<T>() << '\n'; // You don't actually need the
// typedef in this case, but
// for it to work with the
// typeid below, you'll need it
// Using typeid().name()
std::cout << typeid(float).name() << '\n';
std::cout << typeid(T).name() << '\n';
return 0;
}
The code above results in the following output with GCC flag -s ("strip all symbols from binary") enabled:
float
void (*)(int, int)
f
PFviiE
So, you see, getTypename() does a fairly better job, at the cost of that fugly string parsing hack (I KNOW, it's damn ugly).
A few points to take into account:
The code is GCC only. I don't know how to port it to another compiler. Probably only a few others have such a facility to produce so pretty function names, and from what I searched, MSVC++ doesn't have one, if you're asking yourself that.
If, in a new version, GCC formats __PRETTY_FUNCTION__'s differently, the string matching can break and you'll have to fix it. For this same reason I also warn that getTypeName() might be good for debugging (and, still, maybe not even good for that), but it is surely bad, bad, and bad for other purposes such as comparing two types in a template or something like that (I don't know, just guessing what someone might think of..). Use it solely for debugging, and preferentially don't call it in release builds (use macros to disable), so that you don't use __PRETTY_FUNCTION__ and thus the compiler doesn't produce the string for it.
I'm definitely no expert, and I'm not sure whether some odd type could cause the string matching to fail. I'd like to ask for people who read this post to comment if they know of such a case.
The code uses a static std::string. It means that, if some exception is thrown from its constructor or destructor, there is no way that it will reach a catch block and you'll get an unhandled exception. I don't know whether std::strings can do that, but beware that, if they do, you're potentially in trouble. I used it because it needs a destructor to free the memory. You could implement your own class for that, though, ensuring no exception is thrown besides allocation failure (that's pretty much fatal, isn't it? So...), and return a simple C-string.
With typedefs you can get some weird results, like this (for some reason, the site breaks the formatting of this snippet, so I'm using this paste link): http://pastebin.com/f51b888ad
Despite those disadvantages, I'd like to say that it sure is fast. For the second time you lookup for one same type name, it will cost picking a reference to a global std::string containing the name. And, comparatively to the template specialiazation methods suggested before, there is nothing else you have to declare besides the very template itself, so it is really much easier to use.
No, you cannot work on types as if they were variables. You could write code that extracted the typeid() of an element and printed the name, but the resulting value will probably not be what you expect (type names are not standarized).
You can also work with template specializations (and some macro magic) to achieve a more interesting version if the number of types you want to work with is limited:
template <typename T> const char* printtype(); // not implemented
// implement specializations for given types
#define DEFINE_PRINT_TYPE( type ) \
template<>\
const char* printtype<type>() {\
return #type;\
}
DEFINE_PRINT_TYPE( int );
DEFINE_PRINT_TYPE( double );
// ... and so on
#undef DEFINE_PRINT_TYPE
template <typename T> void test()
{
std::cout << printtype<T>() << std::endl;
}
int main() {
test<int>();
test<double>();
test<float>(); // compilation error, printtype undefined for float
}
Or you could even combine both versions: implement the printtype generic template using typeinfo and then provide specializations for the types you want to have fancier names.
template <typename T>
const char* printtype()
{
return typeid(T).name();
}
This breaks one of my primary tenets of C++ code writing: Avoid using tricks in both the template features and the preprocessor at the same time.
Part of the reason for templates and the nastiness they introduce into the language was an attempt to wean developers away from using the preprocessor. If you use both, then the terrorists win.
If you use boost/core/demangle.hpp, you can get a reliable human-readable string.
char const * name = typeid(T).name();
boost::core::scoped_demangled_name demangled( name );
std::cout << (demangled.get() ? demangled.get() : "Failed to demangle") << std::endl;
in my code I use the "awful" double-declaration of the "Class-Name"
MqFactoryC<MyServer>::Add("MyServer").Default();
because c++ is NOT able to extract the string "MyServer" from the template…
the only "way" to get "rid" of this… using a cpp "wrapper"
#define MQ_CPPSTR(s) #s
#define MqFactoryCAdd(T) MqFactoryC<T>::Add(MQ_CPPSTR(T)).Default()
Here’s what I do: I have a demangle() function (implemented on top of abi::__cxa_demangle() which I call with a couple of convenience template function overloads, nameof(), with either the type I want stringified or an instance of same.
It’s fairly compact, so I’ll reproduce it here in all its glory. In demangle.hh we have:
#pragma once
#include <typeinfo>
namespace terminator {
/// actual function to demangle an allegedly mangled thing
char const* demangle(char const* const symbol) noexcept;
/// convenience function template to stringify a name of a type,
/// either per an explicit specialization:
/// char const* mytypename = terminator::nameof<SomeType>();
template <typename NameType>
char const* nameof() {
try {
return demangle(typeid(NameType).name());
} catch (std::bad_typeid const&) {
return "<unknown>";
}
}
/// … or as implied by an instance argument:
/// char const* myinstancetypename = terminator::nameof(someinstance);
template <typename ArgType>
char const* nameof(ArgType argument) {
try {
return demangle(typeid(argument).name());
} catch (std::bad_typeid const&) {
return "<unknown>";
}
}
} /* namespace terminator */
… And then in demangle.cpp:
#include "demangle.hh"
#include <cstdlib>
#include <cxxabi.h>
#include <mutex>
#include <memory>
namespace terminator {
namespace {
/// define one singular, private, static std::mutex,
/// to keep the demangler from reentering itself
static std::mutex mangle_barrier;
/// define a corresponding private and static std::unique_ptr,
/// using a delete-expression to reclaim the memory malloc()'ed by
/// abi::__cxa_demangle() upon its return.
/// … we use clang pragmas to add flags locally for this to work:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wglobal-constructors"
#pragma clang diagnostic ignored "-Wexit-time-destructors"
std::unique_ptr<char, decltype(std::free)&> demangled_name{ nullptr, std::free };
#pragma clang diagnostic pop
}
char const* demangle(char const* const symbol) noexcept {
if (!symbol) { return "<null>"; }
std::lock_guard<std::mutex> lock(mangle_barrier);
int status = -4;
demangled_name.reset(
abi::__cxa_demangle(symbol,
demangled_name.get(),
nullptr, &status));
return ((status == 0) ? demangled_name.release() : symbol);
}
} /* namespace terminator */
To use this, I think you’ll have to link to libc++ (or whatever your local equivalent is) to use abi::__cxa_demangle(). What may be suboptimal for the OP is the fact that this does the demangling and stringification at runtime. I’d personally love something constexpr-friendly in leu of this, but since I suffer from a severe macro-abuse allergy, I find this to be the least generally-unreasonable solution to this problem.
(the terminator namespace is inconsequential – I use this code in a libunwind-based stacktracer called from termination handler – feel free to s///g that token)