Why would *&param be used in a function? - c++

I've been trying to make sense of LLVM's instruction combining code and noticed this function:
static void detectLog2OfHalf(Value *&Op, Value *&Y, IntrinsicInst *&Log2) {
if (!Op->hasOneUse())
return;
IntrinsicInst *II = dyn_cast<IntrinsicInst>(Op);
if (!II)
return;
if (II->getIntrinsicID() != Intrinsic::log2 || !II->hasUnsafeAlgebra())
return;
Log2 = II;
Value *OpLog2Of = II->getArgOperand(0);
if (!OpLog2Of->hasOneUse())
return;
Instruction *I = dyn_cast<Instruction>(OpLog2Of);
if (!I)
return;
if (I->getOpcode() != Instruction::FMul || !I->hasUnsafeAlgebra())
return;
if (match(I->getOperand(0), m_SpecificFP(0.5)))
Y = I->getOperand(1);
else if (match(I->getOperand(1), m_SpecificFP(0.5)))
Y = I->getOperand(0);
}
Why would *& by used in the parameters? Does it have some meaning or would Op be equivalent to *&Op?

Why would *& by used in the parameters?
In a function parameter list, this parameter
IntrinsicInst *&Log2
is a reference to pointer to Value. It means the function can modify the pointer itself, and this is seen at the caller side. In this case, that happens here:
Log2 = II;
If Log2 was not passed by reference, the above line would only have an effect in the scope of the function.
... would Op be equivalent to *&Op?
Not in this context. In a different one, yes. For example, when * is the de-reference operator and & is the address-of operator, then *&x would mean "de-reference the result of applying the address-of operator to x", that is, de-reference a pointer to x. C++ confusingly re-uses symbols depending on context. Most of this is inherited from C. On top of that, changes to C++ should not break existing code. The easiest way to do this is to re-use symbols.

& means reference.
value * means value is a pointer.
value *&op is equalent to passing pointer by reference, so if we change value in the function it will be reflected in the called function.

Related

Why is the return type of the function not consistent with the actual sentence? [duplicate]

This question already has answers here:
What happens when I call a function without assigning its returned value to a variable? [duplicate]
(4 answers)
Closed 5 years ago.
In the program, it has:
EnergyFunctional* ef;
ef->insertFrame(fh, &Hcalib);
The function is defined as follows:
EFFrame* EnergyFunctional::insertFrame(FrameHessian* fh, CalibHessian* Hcalib)
{
EFFrame* eff = new EFFrame(fh);
eff->idx = frames.size();
frames.push_back(eff);
nFrames++;
fh->efFrame = eff;
assert(HM.cols() == 8*nFrames+CPARS-8); /// CPARS = 4
bM.conservativeResize(8*nFrames+CPARS);
HM.conservativeResize(8*nFrames+CPARS,8*nFrames+CPARS);
bM.tail<8>().setZero();
HM.rightCols<8>().setZero();
HM.bottomRows<8>().setZero();
EFIndicesValid = false;
EFAdjointsValid=false;
EFDeltaValid=false;
setAdjointsF(Hcalib);
makeIDX();
for(EFFrame* fh2 : frames)
{
connectivityMap[(((uint64_t)eff->frameID) << 32) + ((uint64_t)fh2->frameID)] = Eigen::Vector2i(0,0); /// move left 32 bits
if(fh2 != eff)
connectivityMap[(((uint64_t)fh2->frameID) << 32) + ((uint64_t)eff->frameID)] = Eigen::Vector2i(0,0); /// index is totally 64 bits, front 32 bits for each frame, rear 32 bits for current frame
}
return eff;
}
It seems like the return type should be void so that it can be consistent with last sentence...
I also checked if there is other same name "inserFrame" functions, but there is not.
This program can be compiled successfully, but why can it be no problem?
The return type specified by the function is EFFrame*, which is a pointer to an EFFrame object. The value being returned by the function is eff, which is a EFFrame* type pointer as well. So there shouldn't be any confusion.
You would only use a void return type in the function declaration if you are not returning a value. However, as shown in the last line, this function is clearly trying to return a pointer to a EFFrame object.
However, even in functions that have a clearly defined return type, it may not be necessary to use that value. Hence it is technically legal to just call the function and not store the return value into a variable. Hence, even though ef->insertFrame(fh, &Hcalib); is calling the function and returning a EFFrame* pointer, it just isn't being stored.

the increment of a returned value

I have defined a function like this:
int test(int n) {
const int b = n;
return b;
}
While in the main function, I use like this:
int temp = test(50)++;
And the g++ reports an error:
error: lvalue required as increment operand
Actually, I'm fully confused by this. Would you like to give me some tips or explain it to me.
You can only apply ++ to an lvalue (at least of built-in type). The return value from a function can be an lvalue if if it returns a reference, but otherwise it's an rvalue (in which case, you can't apply ++ to it).
The value returned from test is an rvalue. You cannot use the increment operator (++) on it. You can change your calling code to:
int temp = test(50);
temp++;
or
int temp = test(50) + 1;
Once constant value get intialised you cant not change that value.So its giving error try to execute same function without increamenting const value.
'plusplus' operator is (almost) equivalent to '+= 1' that is 'assign the variable its previous value incremented by one'. The value returned is not a variable, so it can not be the left-side argument of an assignment. That's why the increment operator is not applicable here. Just do
t = test(50) + 1;
or
t = test(50);
t ++;

C++ Guidance: Understanding How Pointers Work

I found a code snippet on the internet. When I compile and run it, the output is 70. but i don't know whats happening in the code. please help me out.
#include <iostream>
using namespace std;
void doubleNumber (int *num )
{
*num = *num * 2;
}
int main ()
{
int num = 35;
doubleNumber (&num) ;
cout <<num ;
return 0;
}
void doubleNumber (int *num ) takes a pointer to an integer as parameter, which permits the method to modify the original variable.
Calling *num dereferences the pointer, while *num = *num * 2 assigns the value of the variable of the pointer num multiplied by 2 to the memory cell where num points to.
And in the main, where you have declared the integer, by calling the function doubleNumber with &num, you reference the variable and the return value of that is the pointer to the variable.
int num = 35;
doubleNumber(&num);
Is equivalent to:
int num = 35;
int* num_pointer = &num;
doubleNumber(num_pointer);
You should probably take a look at this site to read about referencing and dereferencing.
In your main function you call doubleNumber() passing a pointer to num.
The doubleNumber() function receives the pointer and doubles his value.
*num = *num * 2
The code defines a function which "doubles" an number. The main program passes the pointer to the variable num in to the function, and the function doubles the variable using the pointer passed in.
Pointers in C++ are my favorite (and - for newer programmers - are often confusing because they are learned in tandem with referencing (& operator). The * symbol is used for a lot of 'stuff' in C++, and it is not helped by the fact that, with pointers, the * symbol does two different things, for which we have two (2) names: dereferencing and indirection.
When we declare a pointer to a type, e.g. int *intPtr = //CODE HERE, we enable the variable to accept an address *intPtr and assign the address in memory of the rvalue (that on the right side of the binary operator) to the variable intPtr. intPtr - or, the address of the rvalue - can then, itself, be passed around and used as an lvalue. We call this "dereferencing".
Then, when we want to access the value of the thing stored at the memory address, we use the indirection operator * in the body of the code to access the stored value. So, let's say we do this:
int num = 35;
int num2 = 0;
int *intPtr = &num; // here using the reference operator & to assign the address
// of num to intPtr
We can then access the value stored behind num by going:
num2 = *intPtr;
Here, the * indirection operator is actually doing something else: it is used to access the value stored at the address stored in intPtr.
WHERE THE CONFUSION HAPPENS:
So, when we see a function header with a pointer as an argument, it's like "Wha'? Which * is being used?"
returntype functionIdentifier(type *num)
In this case, what is received as an argument is a memory address. Then, the argument can be used throughout the body of the function. Too, the indirection operator * can be used to access the value stored at the memory address stored in the passed-in argument (pointer - in this came num).

What is the equivalent of C++ '*&' in C ?. Does it even exist?

for example, how to implement this C++ code in C ?
void someFunction(type *&outParamOnly) ;
returnType someOtherFunction() ;
...
returnType someOtherFunction()
{
type *data = NULL ;
someFunction(data) ;
...
}
...
void someFunction(type *&outParamOnly)
{
bool condition ;
int array_len ;
...
if(condition) // variable's value passed to this function stays as it was
return ;
...
outParamOnly = new type[array_len] ; // value is moddified and it's reflected in 'someOtherFunction'
...
}
...
I'm asking because I don't know how to create such equivalent. Does it's complex ?. In fact I don't know much about C, but much more about C++ syntax, etc. I'm used to write in C++ and once I tryied C to feel diffrence I'm not doing well when trying to implement what I want. I expect positive answer - that it possible to create some equivalent,
but will it be running faster then in C++ or slower ?
Please answer.
The nearest equivalent is a pointer to a pointer; **. C doesn't have references.
There is a slight difference in the call and the function; you must send a pointer to the variable and dereference it when you want to use it:
void someFunction(type **outParamOnly)
...
*outParamOnly = whatever;
}
someFunction(&data);
This is a fairly typical pattern in C.
You'll need to change the function to accept a pointer-to the thing to be modified. In this case, since the value is a pointer, you'll need to declare the function to accept a double-pointer.
Then, when calling the function, pass the address of the value to be modified.
someFunction(&data) ;
...
void someFunction(type **outParamOnly)
{
*outParamOnly = whatever;
Or, you could return the value from the function instead of returning void.
C has no reference types, so there's no easy "equivalent" for the syntax you are asking about.
One can use a pointer-to-pointer to emulate that behavior. I'm not sure if that's the appropriate solution, though. Why not just return the value instead of messing around with various levels of pointers if it's an output argument anyway?
C doesn't have references, but the equivalent is just 'type **'.
void someFunction(type **outParamOnly)
{
if( NULL != outParamOnly )
*outParamOnly = new type[array_len] ;
}
returnType someOtherFunction()
{
type *data = NULL ;
someFunction(&data) ;
}
Note that you need the extra dereference when assigning to what's pointed by outParamOnly and you need to pass a pointer to data when calling someFunction.

What does DetourAttach(&(PVOID &)BindKeyT, BindKeyD); mean? Attaching a detour to a memory address

This is just a simple question. I've been reading the source of something which attaches to a memory address of a subroutine using DetourAttach(&(PVOID &)BindKeyT, BindKeyD); where BindKeyT is the address to a subroutine in memory. I'm curious, what exactly does (&(PVOID &) mean in english? I understand that PVOID is a void pointer, but how does this get translated into a function which can be used to attach a detour to?
Terry Mahaffey is right, what you are passing is a pointer to a pointer to the function. This is commonly used whenever the function you are passing the pointer to (in this case, DetourAttach) wants to return more than one value, and one of those returned values is a pointer. Since functions in C/C++ can only return a single value, the only way to obtain multiple values from them is via pointers.
A simple example would be when one wishes to return a pointer to a block of allocated memory. Then one can write a function like:
int allocstr(int len, char **retptr)
{
char *p = malloc(len + 1); /* +1 for \0 */
if(p == NULL)
return 0;
*retptr = p;
return 1;
}
To answer your other question, of how to setup a memory address to be used as a function, one can do it like so:
void* (void * BindKeyT)(const char* key) = actual_BindKeyT;
// actual_BindKeyT is a pointer to a function that will be defined elsewhere,
// and whose declaration you will include in your project through a header file
// or a dll import
void * BindKeyD(const char* key)
{
// Code for your hook function
}
DetourAttach(&(PVOID&)BindKeyT, BindKeyD);
(taken from http://zenersblog.blogspot.com/2008/04/api-hooking-with-detours-part-1.html)
Bear in mind that the declarations for BindKeyT and BindKeyD should match.
The C++ parser in my head (which is not bug free) says that it is a C style cast of BindKeyT to a reference to a pointer to void - the (PVOID&) part - and then taking the address of that - the & in front. So the result of the expression is a pointer to a pointer to the function.
There is an introduction to Detours here: api-hooking-with-detours-part-1