I posted this Q to TI's 28xx DSP forum but haven't heard a response and figured maybe someone here might know.
I know how to write functions in assembly so that they are C-callable; if the C-callable name is foo() then the assembly function is named _foo().
What if I want to use C++ and optimize a class method in assembly? How do I do that? I assume the only major issues are:
naming
accessing the "this" pointer
accessing class members by somehow knowing offsets
and if I don't want to worry about the last two, then perhaps I would write a static member function and do this:
class MyClass
{
int x;
static int _doSomething(int u); // implement this in assembly
public:
inline void doSomething() { x = _doSomething(x); }
// lightweight C++ wrapper to handle the class member / "this" pointer stuff
};
The this pointer gets passed as an additional argument to the function, using the standard calling convention on your platform. On all the platforms I'm familiar with it is passed as the first argument, but I don't do a lot of C++ coding, so I'm not sure if this is guaranteed by the standard. You can always disassemble some C++ code on your platform to confirm.
The C++ symbol naming is rather more painful than in C, and varies from compiler to compiler. I suppose you could figure out the right symbol name to use by disassembling a compiled function definition, just make sure that: the function is a member of the right class, and has the right number and type of arguments.
Unless you really need to reproduce a C++ function in situ, I would probably just make a standard C function and do the usual extern "C" { ... } around its declaration.
Does your compiler have an inline assembly syntax? If you have that, it may be the easiest option, and you can let the compiler handle the function naming and call syntax pieces.
Alternately, Stephen's suggestion of writing the C++ method as an inlined wrapper around a "simple" C function call is a good one. (You probably want to make it just a plain function, not a static member function as in your post, to get a simple C interface to it.)
I would find the compiler-dependent flag and write the assembly within the C++ function. Usually there are ways to reference local variables from within the assembly section.
Related
I have couple questions regarding some C++ rules.
Why am I able to call a function/method from outside the class in the namespace when I include the return type? (look at the namespace test2::testclass2 in the code below) i.e. this works:
bool b = testclass1::foo<int>(2);
whereas this doesn't: - (it doesn't even compile - compiler throws that this is function redeclaration)
testclass1::foo<int>(2);
C++ complains that it is a function redeclaration. Is that so?
This line:
bool b = testclass1::foo<int>(2);
gets called first before anything else. Is this because static methods get created always first before anything else in C++?
Where can I find those rules? I have a few C++ books at home, so if someone would be kind enough to either point out a book (and chapter or page) or direct me to a website I would greatly appreciate it.
Here below is the sample (partial) code that I tested at home with Visual Studio 2008:
class testclass1
{
public:
testclass1(void);
~testclass1(void);
template<class A> static bool foo(int i)
{
std::cout <<"in static foo";
return true;
}
};
namespace test2
{
class testclass2
{
public:
testclass2(void);
~testclass2(void);
};
bool b = testclass1::foo<int>(2);
}
EDIT:
A few people mentioned that I need to call this inside the function and this will work without any problem.
I understand that; the only reason I asked this question is because I saw this code somewhere (in someone's elses project) and was wondering how and why this works. Since I never really seen anyone doing it before.
Also, this is used (in multiple places) as a way to call and instantiate a large number of classes like this via those function calls (that are outside). They get called first before anything else is instantiated.
C++ is not Python. You write statements in functions and execution starts from the main method. The reason bool b = ... happens to work is that it's defining the global variable b and the function call is merely the initialization expression.
Definitions can exist outside functions while other statements can only exist inside a function body.
Why am I able to call a function/method from outside the class in the namespace when I include the return type? (look at the namespace test2::testclass2)
Your declaration of b is not inside a function, so you are declaring a global variable. If you were inside a function's scope, your second statement would work, but outside a function it makes no sense.
This also answers your second question.
Of course, you wouldn't be allowed to call it this way (i.e. not as a method of an object) if it weren't a static member function.
You can find the rules on e.g. Koenig lookup and template in the standard documentation -- good luck with navigating that! You're not mentioning which compiler you are testing, but I'm not entirely sure it's compliant!
As Mehrdad points out, you're declaring and initializing a global variable within the test2 namespace: this has nothing to do with static methods.
if you write this inside a function like below then it works without a problem. As mentioned above, you need to call these functions from within a function unless you are using the function to initialize a global variable ...
int main()
{
testclass1::foo<int>(2);
return 0;
}
1. First, a helpful correction: you said "...when I include the return type". I think you might be misunderstanding what the <int> part of testclass1::foo<int>(2) does. It doesn't (necessarily) specify the return type, it just provides a value for the template argument "A".
You could have chosen to use A as the return type, but you have the return type hard-coded to "bool".
Basically, for the function as you have written it you will always need to have the <> on it in order to call it. C++ does allow you to omit the <args> off the function when the type can be deduced from the function arguments; in order to get it to do that you have to use the type argument A in your function arguments. For instance if you declared the function this way instead then you could call it without the <>:
template<class A> static bool foo(A i);
In which case it you could call "foo(2)" and it would deduce A to be "int" from the number two.
On the other hand there isn't any way to make it deduce anything based on what you assign the function to. For template argument deduction it only looks at the arguments to the function, not what is done with the result of calling the function. So in:
bool b = testclass1::foo(2);
There is no way to get it to deduce "bool" from that, not even if you made A the return type.
So why doesn't the compiler just tell you "you needed to use <> on the function"? Even though you declared foo once as a template function, you could have also overloaded it with a non-template version too. So the compiler doesn't just automatically assume that you're trying to call a template function when you leave the <> off the call. Unfortunately having NOT assumed you were calling template-foo and not seeing any other declaration for foo, the compiler then falls back on an old C style rule where for a function that takes an int and returns an int, in a very old dialect of C you didn't need to declare that kind of before using it. So the compiler assumed THAT was what you wanted - but then it notices that template-foo and old-crufty-C-foo both take an int parameter, and realizes it wouldn't be able to tell the difference between them. So then it says you can't declare foo. This is why C++ compilers are notorious for giving bad error messages - by the time the error is reported the compiler may have gone completely off the rails and be talking about something that is three or four levels removed from your actual code!
2. Yes you're exactly right.
3. I find that the C++ references and whitepapers that IBM makes available online are the most informative. Here's a link to the section about templates: C++ Templates
I'm calling a function with __func__ as one of the parameters so I can store the name of the function calling that function without having to retype the name of the calling function.
Is there a way of also getting the address of the calling function - a sort of getaddress(__func __) ??
The address will not tell you much; may I instead suggest the predefined macros __FILE__ and __LINE__? They will tell you the current source file (as a char*) and the current line. When you call a function passing those as parameters, you'd know which file/line was the function called from.
They're evaluated by the compiler at the point of usage. If you use them inside the function as opposed to passing them as parameters, they'll tell you the file/line of the function itself.
You can declare function pointers and then assign specific functions to them. So then you could have an array or other collection of such pointers as your table.
If this works for you and you accept the answer, I'm willing to come back and create a short summary here. (I know I'm not supposed to answer with just-a-link.) But see if this approach will do what you want.
https://www.learncpp.com/cpp-tutorial/78-function-pointers/
There is no portable standard C++ way to do this. You could use compiler/OS specific hacks, the same was as in C, but it's less useful in C++ since it only works on extern "C" names (where the __FUNCTION__/__func__ match what dlsym expects).
Since that hack only works on extern "C" names, this means you can't use it for templated functions, class methods, or function overloading (same function name, different argument prototypes), which is fairly restrictive. Mind you, even typing out the function name wouldn't work in some of those cases already (e.g. the name alone doesn't describe the prototype, so function overloading wouldn't work).
I think you need to rethink a design that's essentially demanding reflection in C++; the nature of optimizing compilers is that most of the functions you define don't actually have to exist, or if they do, they exist only with names that are meaningless to anything but the compiler. When you ask to dynamically determine the address of the current function from within the function, you're assuming the function exists, with an actual address, in the final compiled binary, when it could just as easily have been inlined into each actual call site, partially merged with a near identical function, etc.
I find it quite odd that unused virtual functions must still be defined unlike unused ordinary functions. I understand somewhat about the implicit vtables and vpointers which are created when a class object is created - this somewhat answers the question (that the function must be defined so that the pointers to the virtual function can be defined) but this pushes my query back further still.
Why would a vtable entry need to be created for a function if there's absolutely no chance that virtual function will be called at all?
class A{
virtual bool test() const;
};
int main(){
A a; //error: undefined reference to 'vtable for A'
}
Even though I declared A::test() it was never used in the program but it still throws up an error. Can the compiler not run through the program and realise test() was never called - and thus not require a vtable entry for it? Or is that an unreasonable thing to expect of the compiler?
Because it would inevitably be a very difficult problem to solve on the compiler writer's part, when the usefulness of being able to leave virtual functions undefined is at best dubious. Compiler authors surely have better problems to solve.
Besides, you ARE using that function even though you don't call it. You are taking its address.
The OP says that he already knows about vtables and vpointers, so he understands that there is a difference between unused virtual functions and unused non-virtual functions: an unused non-virtual function is not referenced anywhere, while a virtual function is referenced at least once, in the vtable of its class. So, essentially the question is asking why is the compiler not smart enough to refrain from placing a reference to a virtual function in the vtable if that function is not used anywhere. That would allow the function to also go undefined.
The compiler generally sees only one .cpp file at a time, so it does not know whether you have some source file somewhere which invokes that function.
Some tools support this kind of analysis, they call it "global" analysis or something similar. You might even find it built-in in some compilers, and accessible via some compiler option. But it is never enabled by default, because it would tremendously slow down compilation.
As a matter of fact, the reason why you can leave a non-virtual function undefined is also related to lack of global analysis, but in a different way: if the compiler knew that you have omitted the definition of a function, it would probably at least warn you. But since it does not do global analysis, it can't. This is evidenced by the fact that if you do try to use an undefined function, the error will not be caught by the compiler: it will be caught by the linker.
So, just define an empty virtual function which contains an ASSERT(FALSE) and proceed with your life.
The whole point of virtual functions is that they can be called through a base class pointer. If you never use the base class virtual function, then, why did you define it ? If it is used, they you either have to leave the parent implementation (if it's not pure virtual), or define your own implementation, so that code using your objects through the base class can actually make use of it. In that case, the function is used, it's just not used directly.
I'm creating Haskell bindings for a C library. However, I want to adapt the calling conventions of the library to something more appropriate for Haskell so I've created a template class which has a static method that invokes the correct method when you use it the following way:
Wrap<decltype(&libraryFunction), &libraryFunction>::call(...);
Where ... denotes the arguments. This is great, the compiler has generated the wrapper code for me apparently. I can even take the address of this function using the & operator so it's apparently just a regular function.
However, Haskell cannot use C++ templates so what I'd like to do is to explicitly instantiate this template for the required functions and export them as regular C function which I can reference from Haskell. I know I could just make stubs that manually invoke this static member function but let's say I don't really feel like it.
Any ideas on how to do this? Portable or non-portable, I'd like to know if it's possible.
This cannot be done portably:
[temp]/4
A template, a template explicit specialization, and a class template partial specialization shall not have C linkage.
Note that this also prevents you from taking a pointer to that function letting Haskell call the function via this pointer: It is not guaranteed that e.g. the calling convention of a C++ function (in the C++ program) is the same that Haskell assumes for the function pointer it gets.
What can be done portably is to export a single extern "C" function that translates between C and C++ language linkage. You can pass function pointers or other kinds of identifiers to Haskell, and Haskell calls this single C function passing the identifier of the function it actually wants to call:
std::map<int, void(*)(int32_t)> functions;
extern "C" interface_fct(int id, int32_t arg)
{
functions[id](arg);
}
This of course is not very useful for functions with different parameter sets.
You could write something similar to va_args (but safer) to pass arbitrary arguments, but it might be more useful to write something nonportable.
I have couple questions regarding some C++ rules.
Why am I able to call a function/method from outside the class in the namespace when I include the return type? (look at the namespace test2::testclass2 in the code below) i.e. this works:
bool b = testclass1::foo<int>(2);
whereas this doesn't: - (it doesn't even compile - compiler throws that this is function redeclaration)
testclass1::foo<int>(2);
C++ complains that it is a function redeclaration. Is that so?
This line:
bool b = testclass1::foo<int>(2);
gets called first before anything else. Is this because static methods get created always first before anything else in C++?
Where can I find those rules? I have a few C++ books at home, so if someone would be kind enough to either point out a book (and chapter or page) or direct me to a website I would greatly appreciate it.
Here below is the sample (partial) code that I tested at home with Visual Studio 2008:
class testclass1
{
public:
testclass1(void);
~testclass1(void);
template<class A> static bool foo(int i)
{
std::cout <<"in static foo";
return true;
}
};
namespace test2
{
class testclass2
{
public:
testclass2(void);
~testclass2(void);
};
bool b = testclass1::foo<int>(2);
}
EDIT:
A few people mentioned that I need to call this inside the function and this will work without any problem.
I understand that; the only reason I asked this question is because I saw this code somewhere (in someone's elses project) and was wondering how and why this works. Since I never really seen anyone doing it before.
Also, this is used (in multiple places) as a way to call and instantiate a large number of classes like this via those function calls (that are outside). They get called first before anything else is instantiated.
C++ is not Python. You write statements in functions and execution starts from the main method. The reason bool b = ... happens to work is that it's defining the global variable b and the function call is merely the initialization expression.
Definitions can exist outside functions while other statements can only exist inside a function body.
Why am I able to call a function/method from outside the class in the namespace when I include the return type? (look at the namespace test2::testclass2)
Your declaration of b is not inside a function, so you are declaring a global variable. If you were inside a function's scope, your second statement would work, but outside a function it makes no sense.
This also answers your second question.
Of course, you wouldn't be allowed to call it this way (i.e. not as a method of an object) if it weren't a static member function.
You can find the rules on e.g. Koenig lookup and template in the standard documentation -- good luck with navigating that! You're not mentioning which compiler you are testing, but I'm not entirely sure it's compliant!
As Mehrdad points out, you're declaring and initializing a global variable within the test2 namespace: this has nothing to do with static methods.
if you write this inside a function like below then it works without a problem. As mentioned above, you need to call these functions from within a function unless you are using the function to initialize a global variable ...
int main()
{
testclass1::foo<int>(2);
return 0;
}
1. First, a helpful correction: you said "...when I include the return type". I think you might be misunderstanding what the <int> part of testclass1::foo<int>(2) does. It doesn't (necessarily) specify the return type, it just provides a value for the template argument "A".
You could have chosen to use A as the return type, but you have the return type hard-coded to "bool".
Basically, for the function as you have written it you will always need to have the <> on it in order to call it. C++ does allow you to omit the <args> off the function when the type can be deduced from the function arguments; in order to get it to do that you have to use the type argument A in your function arguments. For instance if you declared the function this way instead then you could call it without the <>:
template<class A> static bool foo(A i);
In which case it you could call "foo(2)" and it would deduce A to be "int" from the number two.
On the other hand there isn't any way to make it deduce anything based on what you assign the function to. For template argument deduction it only looks at the arguments to the function, not what is done with the result of calling the function. So in:
bool b = testclass1::foo(2);
There is no way to get it to deduce "bool" from that, not even if you made A the return type.
So why doesn't the compiler just tell you "you needed to use <> on the function"? Even though you declared foo once as a template function, you could have also overloaded it with a non-template version too. So the compiler doesn't just automatically assume that you're trying to call a template function when you leave the <> off the call. Unfortunately having NOT assumed you were calling template-foo and not seeing any other declaration for foo, the compiler then falls back on an old C style rule where for a function that takes an int and returns an int, in a very old dialect of C you didn't need to declare that kind of before using it. So the compiler assumed THAT was what you wanted - but then it notices that template-foo and old-crufty-C-foo both take an int parameter, and realizes it wouldn't be able to tell the difference between them. So then it says you can't declare foo. This is why C++ compilers are notorious for giving bad error messages - by the time the error is reported the compiler may have gone completely off the rails and be talking about something that is three or four levels removed from your actual code!
2. Yes you're exactly right.
3. I find that the C++ references and whitepapers that IBM makes available online are the most informative. Here's a link to the section about templates: C++ Templates