Question: How can I access a member variable in assembly from within a non-POD class?
Elaboration:
I have written some inline assembly code for a class member function but what eludes me is how to access class member variables. I've tried the offsetof macro but this is a non-POD class.
The current solution I'm using is to assign a pointer from global scope to the member variable but it's a messy solution and I was hoping there was something better that I dont know about.
note: I'm using the G++ compiler. A solution with Intel syntax Asm would be nice but I'll take anything.
example of what I want to do (intel syntax):
class SomeClass
{
int* var_j;
void set4(void)
{
asm("mov var_j, 4"); // sets pointer SomeClass::var_j to address "4"
}
};
current hackish solution:
int* global_j;
class SomeClass
{
int* var_j;
void set4(void)
{
asm("mov global_j, 4"); // sets pointer global_j to address "4"
var_j = global_j; // copy it back to member variable :(
}
};
Those are crude examples but I think they get the point across.
This is all you need:
__asm__ __volatile__ ("movl $4,%[v]" : [v] "+m" (var_j)) ;
Edited to add: The assembler does accept Intel syntax, but the compiler doesn't know it, so this trick won't work using Intel syntax (not with g++ 4.4.0, anyway).
class SomeClass
{
int* var_j;
void set4(void)
{
__asm__ __volatile__("movl $4, (%0,%1)"
:
: "r"(this), "r"((char*)&var_j-(char*)this)
:
);
}
};
This might work too, saving you one register:
__asm__ __volatile__("movl $4, %1(%0)"
:
: "r"(this), "i"((char*)&var_j-(char*)this)
:
);
In fact, since the offset of var_j wrt. this should be known at compile time, the second option is the way to go, even if it requires some tweaking to get it working. (I don't have access to a g++ system right now, so I'll leave this up to you to investigate.)
And don't ever underestimate the importance of __volatile__. Took more of my time that I'd liked to track down bugs that appeared because I missed the volatile keyword and the compiler took it upon itself to do strange things with my assembly.
Related
I a have function with inline assembly that has the following definition:
void __declspec(naked) func()
{
__asm
{
//...
JMP [address]
//...
}
}
This address variable is known only at run time, at main I have:
int main()
{
//...
DWORD address = getAddress();
func();
//...
}
As like that, the code will not compile with the following error message:
error C2094: label 'address' was undefined
How can I work around this problem, knowing that I cannot pass address as a parameter to the func() function?
Could I define address in a namespace? Would it be good practice? Can namespaces be used to promote the scope of a variable (using this variable at diferent functions/scopes)?
you are in C++, the destructors must be called when you leave blocks having instances of classes in the stack, this will not be the case with your JMP, and I do not speak about the value of the stack pointer/frame
C++ have exceptions, use them, for instance give in argument the address of a function without argument to call in your assembly portion, and that function throw the exception you want, and place a try-catch at the destination you want to go
Using policy based design, an EncapsulatedAlgorithm:
template< typename Policy>
class EncapsulatedAlgorithm : public Policy
{
double x = 0;
public:
using Policy::subCalculate;
void calculate()
{
Policy::subCalculate(x);
}
protected:
~EncapsulatedAlgorithm() = default;
};
may have a policy Policy that performs a sub-calculation. The sub-calculation is not necessary for the algorithm: it can be used in some cases to speed up algorithm convergence. So, to model that, let's say there are three policies.
One that just "logs" something:
struct log
{
static void subCalculate(double& x)
{
std::cout << "Doing the calculation" << endl;
}
};
one that calculates:
struct calculate
{
static void subCalculate(double& x)
{
x = x * x;
}
};
and one to bring them all and in the darkness bind them :D - that does absolutely nothing:
struct doNothing
{
static void subCalculate(double& x)
{
// Do nothing.
}
};
Here is the example program:
typedef EncapsulatedAlgorithm<doNothing> nothingDone;
typedef EncapsulatedAlgorithm<calculate> calculationDone;
typedef EncapsulatedAlgorithm<loggedCalculation> calculationLogged;
int main(int argc, const char *argv[])
{
nothingDone n;
n.calculate();
calculationDone c;
c.calculate();
calculationLogged l;
l.calculate();
return 0;
}
And here is the live example. I tried examining the assembly code produced by gcc with the optimization turned on:
g++ -S -O3 -std=c++11 main.cpp
but I do not know enough about Assembly to interpret the result with certainty - the resulting file was tiny and I was unable to recognize the function calls, because the code of the static functions of all policies was inlined.
What I could see is that when no optimization is set for the, within the main function, there is a call and a subsequent leave related to the 'doNothing::subCalculate'
call _ZN9doNothing12subCalculateERd
leave
Here are my questions:
Where do I start to learn in order to be able to read what g++ -S spews out?
Is the empty function optimized away or not and where in main.s are those lines?
Is this design O.K.? Usually, implementing a function that does nothing is a bad thing, as the interface is saying something completely different (subCalculate instead of doNothing), but in the case of policies, the policy name clearly states that the function will not do anything. Otherwise I need to do type traits stuff like enable_if, etc, just to exclude a single function call.
I went to http://assembly.ynh.io/, which shows assembly output. I
template< typename Policy>
struct EncapsulatedAlgorithm : public Policy
{
void calculate(double& x)
{
Policy::subCalculate(x);
}
};
struct doNothing
{
static void subCalculate(double& x)
{
}
};
void func(double& x) {
EncapsulatedAlgorithm<doNothing> a;
a.calculate(x);
}
and got these results:
.Ltext0:
.globl _Z4funcRd
_Z4funcRd:
.LFB2:
.cfi_startproc #void func(double& x) {
.LVL0:
0000 F3 rep #not sure what this is
0001 C3 ret #}
.cfi_endproc
.LFE2:
.Letext0:
Well, I only see two opcodes in the assembly there. rep (no idea what that is) and end function. It appears that the G++ compiler can easily optimize out the function bodies.
Where do I start to learn in order to be able to read what g++ -S spews out?
This site's not for recommending reading material. Google "x86 assembly language".
Is the empty function optimized away or not and where in main.s are those lines?
It will have been when the optimiser was enabled, so there won't be any lines in the generated .S. You've already found the call in the unoptimised output....
In fact, even the policy that's meant to do a multiplication may be removed as the compiler should be able to work out you're not using the resultant value. Add code to print the value of x, and seed x from some value that can't be known at compile time (it's often convenient to use argc in a little experimental program like this, then you'll be forcing the compiler to at least leave in the functionally significant code.
Is this design O.K.?
That depends on a lot of things (like whether you want to use templates given the implementation needs to be exposed in the header file, whether you want to deal with having distinct types for every instantiation...), but you're implementing the design correctly.
Usually, implementing a function that does nothing is a bad thing, as the interface is saying something completely different (subCalculate instead of doNothing), but in the case of policies, the policy name clearly states that the function will not do anything. Otherwise I need to do type traits stuff like enable_if, etc, just to exclude a single function call.
You may want to carefully consider your function names... do_any_necessary_calculations(), ensure_exclusivity() instead of lock_mutex(), after_each_value() instead of print_breaks etc..
I have a super class like this:
class Parent
{
public:
virtual void Function(int param);
};
void Parent::Function(int param)
{
std::cout << param << std::endl;
}
..and a sub-class like this:
class Child : public Parent
{
public:
void Function(int param);
};
void Child::Function(int param)
{
;//Do nothing
}
When I compile the sub-class .cpp file, I get this error
warning C4100: 'param' : unreferenced formal parameter
As a practice, we used to treat warnings as errors. How to avoid the above warning?
Thanks.
In C++ you don't have to give a parameter that you aren't using a name so you can just do this:
void Child::Function(int)
{
//Do nothing
}
You may wish to keep the parameter name in the declaration in the header file by way of documentation, though. The empty statement (;) is also unnecessary.
I prefer using a macro, as it tells not only the compiler my intention, but other maintainers of the code, and it's searchable later on.
The method of commenting out the argument name can easily be missed by people unfamiliar with the code (or me 6 months later).
However, it's a style-issue, neither method is "better" or more optimal with regards to code generated, performance or robustness. To me, the deciding factor is informing others of my intent through a standardized system. Omitting the parameter name and putting in a comment would work equally well:
void CFooBar::OnLvnItemchanged(NMHDR *pNMHDR, LRESULT *pResult)
{
UNREFERENCED_PARAMETER(pNMHDR);
Alternatively:
void CFooBar::OnLvnItemchanged(NMHDR* /* pNMHDR */, LRESULT *pResult)
{
// Not using: pNMHDR
I would say that the worst solution is suppressing the warning message; that that will affect your entire file or project, and you'll lose the knowledge that maybe you've missed something. At least by adding the macro, or commenting out the argument name, you've told others that you've made a conscious decision to not use this argument and that it's not a mistake.
The Windows SDK in WinNT.h defines UNREFERENCED_PARAMETER() along with DBG_UNREFERENCED_PARAMETER() and DBG_UNREFERENCED_LOCAL_VARIABLE(). They all evaluate to the same thing, but the difference is that DBG_UNREFERENCED_PARAMETER() is used when you are starting out and expect to use the parameter when the code is more complete. When you are sure you'll never use the parameter, use the UNREFERENCED_PARAMETER() version.
The Microsoft Foundation Classes (MFC) have a similar convention, with the shorter UNUSED() and UNUSED_ALWAYS() macros.
Pick a style and stick with it. That way later on you can search for "DBG_UNREFERENCED_PARAMETER" in your code and find any instances of where you expected to use a argument, but didn't. By adopting a consistent style, and habitually using it, you'll make it easier for other and yourself later on.
Another technique that you can use if you want to keep the parameter name is to cast to void:
void Child::Function(int param)
{
(void)param; //Do nothing
}
As #Charles Bailey mentioned, you can skip the parameter name.
However, in certain scenarios, you need the parameter name, since in debug builds you are calling an ASSERT() on it, but on retail builds it's a nop. For those scenarios there's a handy macros (at least in VC++ :-)) UNREFERENCED_PARAMETER(), which is defined like this:
#define UNREFERENCED_PARAMETER(x) x
Note that the simple cast #R Samuel Klatchko posted also works, but I personally find it more readable if the code is explicit that this is an unreferenced parameter vs. simple unexplained cast like that.
Pragma works nicely too since it's clear you are using VS. This warning has a very high noise to benefit ratio, given that unreferenced parameters are very common in callback interfaces and derived methods. Even teams within Microsoft Windows who use W4 have become tired of its pointlessness (would be more suitable for /Wall) and simply added to their project:
#pragma warning(disable: 4100)
If you want to alleviate the warning for just a block of code, surround it with:
#pragma warning(push)
#pragma warning(disable: 4100)
void SomeCallbackOrOverride(int x, float y) { }
#pragma warning(pop)
The practice of leaving out the parameter name has the downside in the debugger that you can't easily inspect by name nor add it to the watch (becomes confused if you have more than one unreferenced parameter), and while a particular implementation of a method may not use the parameter, knowing its value can help you figure out which stage of a process you are in, especially when you do not have the whole call stack above you.
Since C++17 you also can use [[maybe_unused]] to avoid such warnings:
class Parent
{
public:
virtual void Function([[maybe_unused]] int param);
};
I would use a macro to suppress the unreferenced formal parameter warning:
#define UNUSED( x ) ( &reinterpret_cast< const int& >( x ) )
This has the following advantages:
Unlike #define UNUSED( x ) ( void )x, it doesn't introduce a need for the full definition of the parameter's type to be seen where no such need may have existed before.
Unlike #define UNUSED( x ) &x, it can be used safely with parameters whose types overload the unary & operator.
What about just adding reference with a comment:
void Child::Function(int param)
{
param; //silence unreferenced warning
}
This was also suggested here: https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-4-c4100?view=vs-2019
(Yes, I know that one machine instruction usually doesn't matter. I'm asking this question because I want to understand the pimpl idiom, and use it in the best possible way; and because sometimes I do care about one machine instruction.)
In the sample code below, there are two classes, Thing and
OtherThing. Users would include "thing.hh".
Thing uses the pimpl idiom to hide it's implementation.
OtherThing uses a C style – non-member functions that return and take
pointers. This style produces slightly better machine code. I'm
wondering: is there a way to use C++ style – ie, make the functions
into member functions – and yet still save the machine instruction. I like this style because it doesn't pollute the namespace outside the class.
Note: I'm only looking at calling member functions (in this case, calc). I'm not looking at object allocation.
Below are the files, commands, and the machine code, on my Mac.
thing.hh:
class ThingImpl;
class Thing
{
ThingImpl *impl;
public:
Thing();
int calc();
};
class OtherThing;
OtherThing *make_other();
int calc(OtherThing *);
thing.cc:
#include "thing.hh"
struct ThingImpl
{
int x;
};
Thing::Thing()
{
impl = new ThingImpl;
impl->x = 5;
}
int Thing::calc()
{
return impl->x + 1;
}
struct OtherThing
{
int x;
};
OtherThing *make_other()
{
OtherThing *t = new OtherThing;
t->x = 5;
}
int calc(OtherThing *t)
{
return t->x + 1;
}
main.cc (just to test the code actually works...)
#include "thing.hh"
#include <cstdio>
int main()
{
Thing *t = new Thing;
printf("calc: %d\n", t->calc());
OtherThing *t2 = make_other();
printf("calc: %d\n", calc(t2));
}
Makefile:
all: main
thing.o : thing.cc thing.hh
g++ -fomit-frame-pointer -O2 -c thing.cc
main.o : main.cc thing.hh
g++ -fomit-frame-pointer -O2 -c main.cc
main: main.o thing.o
g++ -O2 -o $# $^
clean:
rm *.o
rm main
Run make and then look at the machine code. On the mac I use otool -tv thing.o | c++filt. On linux I think it's objdump -d thing.o. Here is the relevant output:
Thing::calc():
0000000000000000 movq (%rdi),%rax
0000000000000003 movl (%rax),%eax
0000000000000005 incl %eax
0000000000000007 ret
calc(OtherThing*):
0000000000000010 movl (%rdi),%eax
0000000000000012 incl %eax
0000000000000014 ret
Notice the extra instruction because of the pointer indirection. The first function looks up two fields (impl, then x), while the second only needs to get x. What can be done?
One instruction is rarely a thing to spend much time worrying over. Firstly, the compiler may cache the pImpl in a more complex use case, thus amortising the cost in a real-world scenario. Secondly, pipelined architectures make it almost impossible to predict the real cost in clock cycles. You'll get a much more realistic idea of the cost if you run these operations in a loop and time the difference.
Not too hard, just use the same technique inside your class. Any halfway decent optimizer will inline
the trivial wrapper.
class ThingImpl;
class Thing
{
ThingImpl *impl;
static int calc(ThingImpl*);
public:
Thing();
int calc() { calc(impl); }
};
There's the nasty way, which is to replace the pointer to ThingImpl with a big-enough array of unsigned chars and then placement/new reinterpret cast/explicitly destruct the ThingImpl object.
Or you could just pass the Thing around by value, since it should be no larger than the pointer to the ThingImpl, though may require a little more than that (reference counting of the ThingImpl would defeat the optimisation, so you need some way of flagging the 'owning' Thing, which might require extra space on some architectures).
I disagree about your usage: you are not comparing the 2 same things.
#include "thing.hh"
#include <cstdio>
int main()
{
Thing *t = new Thing; // 1
printf("calc: %d\n", t->calc());
OtherThing *t2 = make_other(); // 2
printf("calc: %d\n", calc(t2));
}
You have in fact 2 calls to new here, one is explicit and the other is implicit (done by the constructor of Thing.
You have 1 new here, implicit (inside 2)
You should allocate Thing on the stack, though it would not probably change the double dereferencing instruction... but could change its cost (remove a cache miss).
However the main point is that Thing manages its memory on its own, so you can't forget to delete the actual memory, while you definitely can with the C-style method.
I would argue that automatic memory handling is worth an extra memory instruction, specifically because as it's been said, the dereferenced value will probably be cached if you access it more than once, thus amounting to almost nothing.
Correctness is more important than performance.
Let the compiler worry about it. It knows far more about what is actually faster or slower than we do. Especially on such a minute scale.
Having items in classes has far, far more benefits than just encapsulation. PIMPL's a great idea, if you've forgotten how to use the private keyword.
i have a little problem, and I am not sure if it's a compiler bug, or stupidity on my side.
I have this struct :
struct BulletFXData
{
int time_next_fx_counter;
int next_fx_steps;
Particle particles[2];//this is the interesting one
ParticleManager::ParticleId particle_id[2];
};
The member "Particle particles[2]" has a self-made kind of smart-ptr in it (resource-counted texture-class). this smart-pointer has a default constructor, that initializes to the ptr to 0 (but that is not important)
I also have another struct, containing the BulletFXData struct :
struct BulletFX
{
BulletFXData data;
BulletFXRenderFunPtr render_fun_ptr;
BulletFXUpdateFunPtr update_fun_ptr;
BulletFXExplosionFunPtr explode_fun_ptr;
BulletFXLifetimeOverFunPtr lifetime_over_fun_ptr;
BulletFX( BulletFXData data,
BulletFXRenderFunPtr render_fun_ptr,
BulletFXUpdateFunPtr update_fun_ptr,
BulletFXExplosionFunPtr explode_fun_ptr,
BulletFXLifetimeOverFunPtr lifetime_over_fun_ptr)
:data(data),
render_fun_ptr(render_fun_ptr),
update_fun_ptr(update_fun_ptr),
explode_fun_ptr(explode_fun_ptr),
lifetime_over_fun_ptr(lifetime_over_fun_ptr)
{
}
/*
//USER DEFINED copy-ctor. if it's defined things go crazy
BulletFX(const BulletFX& rhs)
:data(data),//this line of code seems to do a plain memory-copy without calling the right ctors
render_fun_ptr(render_fun_ptr),
update_fun_ptr(update_fun_ptr),
explode_fun_ptr(explode_fun_ptr),
lifetime_over_fun_ptr(lifetime_over_fun_ptr)
{
}
*/
};
If i use the user-defined copy-ctor my smart-pointer class goes crazy, and it seems that calling the CopyCtor / assignment operator aren't called as they should.
So - does this all make sense ? it seems as if my own copy-ctor of struct BulletFX should do exactly what the compiler-generated would, but it seems to forget to call the right constructors down the chain.
compiler bug ? me being stupid ?
Sorry about the big code, some small example could have illustrated too. but often you guys ask for the real code, so well - here it is :D
EDIT : more info :
typedef ParticleId unsigned int;
Particle has no user defined copyctor, but has a member of type :
Particle
{
....
Resource<Texture> tex_res;
...
}
Resource is a smart-pointer class, and has all ctor's defined (also asignment operator)
and it seems that Resource is copied bitwise.
EDIT :
henrik solved it... data(data) is stupid of course ! it should of course be rhs.data !!!
sorry for huge amount of code, with a very little bug in it !!!
(Guess you shouldn't code at 1 in the morning :D )
:data(data)
This is problematic. This is because your BulletFXData struct does not have it's own copy-ctor. You need to define one.
Two things jump out at me:
Is this a compiler bug
No. It is never a compiler bug. In twenty years I have seen enumerus complaints,
'it must be a compiler bug' only one has ever turned out to be a bug and that way
back with gcc 2.95 (nowadays gcc is solidly stable (as is dev studio))'
I built my own smart pointer.
Its a nice concept and a nice learning experience. But it is so much harder
to get correct than you think. Especially when you seem to be having trouble with
copy constructors
This is wrong The structure is copy constructed using itself as the object to be copied. Thus you are copy random data into itself.
:Look at comments to see what you should be using as parameters.
//USER DEFINED copy-ctor. if it's defined things go crazy
BulletFX(const BulletFX& rhs)
:data(data), // rhs.data
render_fun_ptr(render_fun_ptr), // rhs.render_fun_ptr
update_fun_ptr(update_fun_ptr), // rhs.update_fun_ptr
explode_fun_ptr(explode_fun_ptr), // rhs.explode_fun_ptr
lifetime_over_fun_ptr(lifetime_over_fun_ptr) // rhs.lifetime_over_fun_ptr
{
}
Of course at this point you may as well use the compiler generated version of the copy constructor as this is exactly what it is doing.