Can a function use its own address in c11? - c

Is the following valid c11 code? I have checked the standard, and it seems unsupported, but I may be missing something. This example is a little contrived, but my actual situation involves like a thousand lines of code and wouldn't make much sense without all that context, and this example correctly isolates the principal I want to ask about. The point is that I use the function's own address by directly using its identifier.
typedef void(*ftype)(void*,void*);
void func(void* v, void* w)
{
if( func != (ftype)v ) ((ftype)v)( ((void**)w)[0], ((void**)w)[1]) );
}
So, the idea is to run the function pointed to by v for its side effects, with its input given by an array pointed to by w. However, it is desired to not run v if it happens to be a reference to the function 'func'.
EDIT: A comment answered the question: "A direct function call involves an implicit conversion ("decay") from the function name to a pointer to the function. Hence, every recursive function effectively takes its own address."

typedef void(*ftype)(void*,void*);
void func(void* v, void* w);
ftype myfunc = func; //here
Since we can take the address of functions that are 100% undefined in each translation unit, there's no reason that C should have a rule that disallows taking the address of a function that's partially defined. And when we check, there is indeed no such exception. Therefore, you can always take the address of a declared function, even inside the function.

Related

Pass by address of value in C

I know the following is an example of pass by reference in C++, input is passed as a reference:
void add(int &input){
++input;
}
I also know pass by reference is not available in C. My question is, does the above syntax mean something else in C (i.e pass by value or something), or is it meaningless?
Trying to compile it in C gives this error:
error: parameter name omitted
does the above syntax mean something else in C?
No, it does not. It's not valid C at all.
The & operator means two things in C. The binary one is bitwise "and", and the unary is "address of". You cannot use it in declarations.
C++ chose this for reference variable for two reasons. The first is that since it is not valid C, it will not collide with existing C code. When C++ came, they focused pretty hard on making C++ backwards compatible with C. In later versions of C++, the backwards compability with C is not a very high priority. To a large degree, this is because C++ was a fork of a pretty early version of C, and since then both languages have evolved somewhat independently. For instance C99 added (but it was removed later) variable length arrays, which were never added to C++. Another example is designated initializers.
The other reason is that the meaning of the operator is pretty similar. You can interpret it as "instead of forcing the caller to send the address, I will take the address of whatever he is sending". They simply just moved the & to the function prototype instead of the function call.
And yes, there are a few other differences between pointers and references too
A reference must be initialized. (Assigned upon declaration)
A reference cannot be reassigned to "point" to another object.
A reference must always "point" at an object. It cannot be NULL.
There is one danger with references. In C, you can be certain that a function will never change the variables you send as arguments to a function unless you're sending the address to them. This C code:
int main(void)
{
int a = 42;
foo(a);
printf("%d\n", a);
}
will ALWAYS print "42", no matter how the function foo is defined. Provided that the code compiles and there's no weird undefined behavior. In C++, you don't have that guarantee.
No, it is simply invalid syntax in C.
That is actually one of the reasons that C++ picked this syntax for the feature: it wouldn't change the meaning of any existing C code.
While C does not have pass by reference (and the code will produce compile error), you can get something closer by following the rules:
In the prototype, replace & with * const (reference cannot be reassigned).
In the body, replace reference to varname with (*varname)
When calling the method, replace arg with &(arg).
void add (int *const in)
{
++(*in) ; // increment
(*in) = 5 ; // assign
int x = *in ; // Copy value
}
does the above syntax mean something else in C (i.e pass by value or something), or it's meaningless?
It is meaningless. The program is syntactically ill-formed .

Are pointers considered a method of calling by reference in C?

In my University's C programming class, the professor and subsequent book written by her uses the term call or pass by reference when referring to pointers in C.
An example of what is considered a 'call by reference function' by my professor:
int sum(int *a, int *b);
An example of what is considered a 'call by value function' by my professor:
int sum(int a, int b);
I've read C doesn't support call by reference. To my understanding, pointers pass by value.
Basically, is it incorrect to say pointers are C's way of passing by reference? Would it be more correct to say you cannot pass by reference in C but can use pointers as an alternative?
Update 11/11/15
From the way my question originated, I believe a debate of terminology has stemmed and in fact I'm seeing two specific distinctions.
pass-by-reference (the term used mainly today): The specific term as used in languages like C++
pass-by-reference (the term used by my professor as a paradigm to explain pointers): The general term used before languages like C++ were developed and thus before the term was rewritten
After reading #Haris' updated answer it makes sense why this isn't so black and white.
you cannot pass by reference in C but can use pointers as an alternative
Yup, thats correct.
To elaborate a little more. Whatever you pass as an argument to c functions, it is passed by values only. Whether it be a variable's value or the variable address.
What makes the difference is what you are sending.
When we pass-by-value we are passing the value of the variable to a function. When we pass-by-reference we are passing an alias of the variable to a function. C can pass a pointer into a function but that is still pass-by-value. It is copying the value of the pointer, the address, into the function.
If you are sending the value of a variable, then only the value will be received by the function, and changing that won't effect the original value.
If you are sending the address of a variable, then also only the value(the address in this case) is sent, but since you have the address of a variable it can be used to change the original value.
As an example, we can see some C++ code to understand the real difference between call-by-value and call-by-reference. Taken from this website.
// Program to sort two numbers using call by reference.
// Smallest number is output first.
#include <iostream>
using namespace std;
// Function prototype for call by reference
void swap(float &x, float &y);
int main()
{
float a, b;
cout << "Enter 2 numbers: " << endl;
cin >> a >> b;
if(a>b)
swap(a,b); // This looks just like a call-by-value, but in fact
// it's a call by reference (because of the "&" in the
// function prototype
// Variable a contains value of smallest number
cout << "Sorted numbers: ";
cout << a << " " << b << endl;
return 0;
}
// A function definition for call by reference
// The variables x and y will have their values changed.
void swap(float &x, float &y)
// Swaps x and y data of calling function
{
float temp;
temp = x;
x = y;
y = temp;
}
In this C++ example, reference variable(which is not present in C) is being used. To quote this website,
"A reference is an alias, or an alternate name to an existing variable...",
and
"The main use of references is acting as function formal parameters to support pass-by-reference..."
This is different then the use of pointers as function parameters because,
"A pointer variable (or pointer in short) is basically the same as the other variables, which can store a piece of data. Unlike normal variable which stores a value (such as an int, a double, a char), a pointer stores a memory address."
So, essentially when one is sending address and receiving through pointers, one is sending the value only, but when one is sending/receiving a reference variable, one is sending an alias, or a reference.
**UPDATE : 11 November, 2015**
There has been a long debate in the C Chatroom, and after reading comments and answers to this question, i have realized that there can be another way to look at this question, another perspective that is.
Lets look at some simple C code
int i;
int *p = &i;
*p = 123;
In this scenario, one can use the terminology that, p's value is a reference to i. So, if that is the case, then if we send the same pointer (int* p) to a function, one can argue that, since i's reference is sent to the function, and thus this can be called pass-by-reference.
So, its a matter of terminology and way of looking at the scenario.
I would not completely disagree with that argument. But for a person who completely follows the book and rules, this would be wrong.
NOTE: Update inspired by this chat.
Reference is an overloaded term here; in general, a reference is simply a way to refer to something. A pointer refers to the object pointed to, and passing (by value) a pointer to an object is the standard way to pass by reference in C.
C++ introduced reference types as a better way to express references, and introduces an ambiguity into technical English, since we may now use the term "pass by reference" to refer to using reference types to pass an object by reference.
In a C++ context, the former use is, IMO, deprecated. However, I believe the former use is common in other contexts (e.g. pure C) where there is no ambiguity.
Does C even have ``pass by reference''?
Not really.
Strictly speaking, C always uses pass by value. You can simulate pass by reference yourself, by defining functions which accept pointers and then using the & operator when calling, and the compiler will essentially simulate it for you when you pass an array to a function (by passing a pointer instead, see question 6.4 et al.).
Another way of looking at it is that if an parameter has type, say, int * then an integer is being passed by reference and a pointer to an integer is being passed by value.
Fundamentally, C has nothing truly equivalent to formal pass by reference or c++ reference parameters.
To demonstrate that pointers are passed by value, let's consider an example of number swapping using pointers.
int main(void)
{
int num1 = 5;
int num2 = 10;
int *pnum1 = &num1;
int *pnum2 = &num2;
int ptemp;
printf("Before swap, *Pnum1 = %d and *pnum2 = %d\n", *pnum1, *pnum2);
temp = pnum1;
pnum1 = pnum2;
pnum2 = ptemp;
printf("After swap, *Pnum1 = %d and *pnum2 = %d\n", *pnum1, *pnum2);
}
Instead of swapping numbers pointers are swapped. Now make a function for the same
void swap(int *pnum1, int *pnum2)
{
int *ptemp = pnum1;
pnum1 = pnum2;
pnum2 = temp;
}
int main(void)
{
int num1 = 5;
int num2 = 10;
int *pnum1 = &num1;
int *pnum2 = &num2;
printf("Before swap, *pnum1 = %d and *pnum2 = %d\n", *pnum1, *pnum2);
swap(pnum1, pnum2);
printf("After swap, *pnum1 = %d and *pnum2 = %d\n", *pnum1, *pnum2);
}
Boom! No swapping!
Some tutorials mention pointer reference as call by reference which is misleading. See the this answer for the difference between passing by reference and passing by value.
From the C99 standard (emphasis mine):
6.2.5 Types
20 Any number of derived types can be constructed from the object and function types, as
follows:
...
— A pointer type may be derived from a function type or an object type, called the referenced type. A pointer type describes an object whose value provides a reference to an entity of the referenced type. A pointer type derived from the referenced type T is sometimes called ‘‘pointer to T’’. The construction of a pointer type from a referenced type is called ‘‘pointer type derivation’’. A pointer type is a complete object type.
Based on the above, what your professor said makes sense and is correct.
A pointer is passed by value to functions. If the pointer points to a valid entity, its value provides a reference to an entity.
"Passing by reference" is a concept. Yes, you are passing the value of a pointer to the function, but in that instance the value of that pointer is being used to reference the variable.
Someone else used a screwdriver analogy to explain that it is wrong to refer to the passing of pointers as passing by reference, saying that you can screw a screw with a coin but that that doesn't mean you would call the coin a screw driver. I would say that is a great analogy, but they come to the wrong conclusion. In fact, while you wouldn't claim a coin was a screwdriver, you would still say that you screwed the screw in with it. i.e. even though pointers are not the same as c++ references, what you are using them to do IS passing by reference.
C passes arguments by value, period. However, pointers are a mechanism that can be used for effectively passing arguments by reference. Just like a coin can be used effectively as a screw driver if you got the right kind of screw: some screws slit are even chosen to operate well with coins. They still don't turn the coins into actual screw drivers.
C++ still passes arguments by value. C++ references are quite more limited than pointers (though having more implicit conversions) and cannot become part of data structures, and their use looks a lot more like the usual call-by-reference code would look, but their semantics, while very much catered to match the needs of call-by-reference parameters, are still more tangible than that of pure call-by-reference implementations like Fortran parameters or Pascal var parameters and you can use references perfectly well outside of function call contexts.
Your professor is right.
By value , it is copied.
By reference, it is not copied, the reference says where it is.
By value , you pass an int to a function , it is copied , changes to the copy does not affect the original.
By reference , pass same int as pointer , it is not copied , you are modifying the original.
By reference , an array is always by reference , you could have one billion items in your array , it is faster to just say where it is , you are modifying the original.
In languages which support pass-by-reference, there exists a means by which a function can be given something that can be used to identify a variable know to the caller until the called function returns, but which can only be stored in places that won't exist after that. Consequently, the caller can know that anything that will be done with a variable as a result of passing some function a reference to it will have been done by the time the function returns.
Compare the C and C# programs:
// C // C#
int x=0; int x=0;
foo(&x); foo(ref x);
x++; x++;
bar(); bar();
x++; x++;
boz(x); boz(x);
The C compiler has no way of knowing whether "bar" might change x, because
foo() received an unrestricted pointer to it. By contrast, the C# compiler
knows that bar() can't possibly change x, since foo() only receives a
temporary reference (called a "byref" in .NET terminology) to it and there
is no way for any copy of that byref to survive past the point where foo()
returns.
Passing pointers to things allows code to do the same things that can be done with pass-by-ref semantics, but pass-by-ref semantics make it possible for code to offer stronger guarantees about things it won't do.

Direct access to the function stack

I previously asked a question about C functions which take an unspecified number of parameters e.g. void foo() { /* code here */ } and which can be called with an unspecified number of arguments of unspecified type.
When I asked whether it is possible for a function like void foo() { /* code here */ } to get the parameters with which it was called e.g. foo(42, "random") somebody said that:
The only you can do is to use the calling conventions and knowledge of the architecture you are running at and get parameters directly from the stack. source
My question is:
If I have this function
void foo()
{
// get the parameters here
};
And I call it: foo("dummy1", "dummy2") is it possible to get the 2 parameters inside the foo function directly from the stack?
If yes, how? Is it possible to have access to the full stack? For example if I call a function recursively, is it possible to have access to each function state somehow?
If not, what's the point with the functions with unspecified number of parameters? Is this a bug in the C programming language? In which cases would anyone want foo("dummy1", "dummy2") to compile and run fine for a function which header is void foo()?
Lots of 'if's:
You stick to one version of a compiler.
One set of compiler options.
Somehow manage to convince your compiler to never pass arguments in registers.
Convince your compiler not to treat two calls f(5, "foo") and f(&i, 3.14) with different arguments to the same function as error. (This used to be a feature of, for example, the early DeSmet C compilers).
Then the activation record of a function is predictable (ie you look at the generated assembly and assume it will always be the same): the return address will be there somewhere and the saved bp (base pointer, if your architecture has one), and the sequence of the arguments will be the same. So how would you know what actual parameters were passed? You will have to encode them (their size, offset), presumably in the first argument, sort of what printf does.
Recursion (ie being in a recursive call makes no difference) each instance has its activation record (did I say you have to convince your compiler never optimise tail calls?), but in C, unlike in Pascal, you don't have a link backwards to the caller's activation record (ie local variables) since there are no nested function declarations. Getting access to the full stack ie all the activation records before the current instance is pretty tedious, error prone and mostly interest to writers of malicious code who would like to manipulate the return address.
So that's a lot of hassle and assumptions for essentially nothing.
Yes you can access passed parameters directly via stack. But no, you can't use old-style function definition to create function with variable number and type of parameters. Following code shows how to access a param via stack pointer. It is totally platform dependent , so i have no clue if it going to work on your machine or not, but you can get the idea
long foo();
int main(void)
{
printf( "%lu",foo(7));
}
long foo(x)
long x;
{
register void* sp asm("rsp");
printf("rsp = %p rsp_ value = %lx\n",sp+8, *((long*)(sp + 8)));
return *((long*)(sp + 8)) + 12;
}
get stack head pointer (rsp register on my machine)
add the offset of passed parameter to rsp => you get pointer to long x on stack
dereference the pointer, add 12 (do whatever you need) and return the value.
The offset is the issue since it depends on compiler, OS, and who knows on what else.
For this example i simple checked checked it in debugger, but if it really important for you i think you can come with some "general" for your machine solution.
If you declare void foo(), then you will get a compilation error for foo("dummy1", "dummy2").
You can declare a function that takes an unspecified number of arguments as follows (for example):
int func(char x,...);
As you can see, at least one argument must be specified. This is so that inside the function, you will be able to access all the arguments that follow the last specified argument.
Suppose you have the following call:
short y = 1000;
int sum = func(1,y,5000,"abc");
Here is how you can implement func and access each of the unspecified arguments:
int func(char x,...)
{
short y = (short)((int*)&x+1)[0]; // y = 1000
int z = (int )((int*)&x+2)[0]; // z = 5000
char* s = (char*)((int*)&x+3)[0]; // s[0...2] = "abc"
return x+y+z+s[0]; // 1+1000+5000+'a' = 6098
}
The problem here, as you can see, is that the type of each argument and the total number of arguments are unknown. So any call to func with an "inappropriate" list of arguments, may (and probably will) result in a runtime exception.
Hence, typically, the first argument is a string (const char*) which indicates the type of each of the following arguments, as well as the total number of arguments. In addition, there are standard macros for extracting the unspecified arguments - va_start and va_end.
For example, here is how you can implement a function similar in behavior to printf:
void log_printf(const char* data,...)
{
static char str[256] = {0};
va_list args;
va_start(args,data);
vsnprintf(str,sizeof(str),data,args);
va_end(args);
fprintf(global_fp,str);
printf(str);
}
P.S.: the example above is not thread-safe, and is only given here as an example...

Set a function pointer to a static address

I'm injecting a DLL into another process and want to call a function that is in that binary based on it's address (0x54315).
How can I actually declare a function, and then set it to this address?
#define FUNC 0x54315
void *myFuncPtr;
int main()
{
myFuncPtr = FUNC; // pretty sure this isn't how
myFuncPtr(); // call it?
}
The existing answers work, but you don't even need a variable for the function pointer. You can just do:
#define myfunc ((void (*)(void))0x54315)
and then call it as myfunc() just like you would an ordinary function. Note that you should change the type in the cast to match the actual argument and return types of the function.
You need to define myFuncPtr as a function pointer, a void* isn't callable.
Best to use a typedef for that:
typedef void (*funptr)(void);
funprt myFuncPtr;
(Assuming your function takes nothing and returns nothing.)
Then you'll get a warning on the assignment - use a type cast to "silence" it, since this is indeed what you need to do.
You're pretty much on your own with this though, if the signature doesn't match, the calling convention is wrong, or the address is wrong, the compiler cannot validate anything and you get to pick up the pieces.
Your code should work once the syntax is corrected to actually be a function pointer. I failed to read it properly for my first version of this answer. Sorry.
As stated by Mat, the proper syntax for a function pointer would be:
void (*myFuncPtr)(void) = (void (*)(void)) FUNC;
This is often simplified by using a typedef since the C function pointer syntax is somewhat convoluted.
Also, you're must be really sure the function to be called is at that same exact address every time your injected DLL runs. I'm not sure how you can be sure of that, though ...
Also, you would need to pay attention to the calling conventions and any arguments the function at FUNC might be expecting, since if you get that wrong you will likely end up with stack corruption.

Pointer to function in ROM

I have microcontroler that I am working with. When debugging it is necessary to call a function from that is hard coded in ROM. Technical Reference shows how to do this:
# define Device_cal (void(*)(void))0x3D7C80
and calling procedure looks like this:
(*Device_cal)()
I can't understand what actually happens here, so my question is:
How does it work?
void (*) (void) is a type. It's a pointer to a function that takes no parameter and returns void.
(void(*)(void)) 0x3D7C80 casts the 0x3D7C80 integer to this function pointer.
(*Device_cal)() calls the function.
(Device_cal)() would do the exactly the same.
The parentheses around *Device_cal and Device_cal are required because otherwise the cast to the integer would not have the higher precedence.
The #define causes (*Device_cal)() to be expanded into this immediately before compiling:
(*(void(*)(void))0x3D7C80)()
The void(*)(void) is a declaration for a function pointer that takes void and returns void types. The (*()) represents a cast for the next token in the expression (0x3D7C80). Thus this asks to treat the data at location 0x3D7C80 as a function. The final () calls the function with no arguments.
well, you "define" a pointer to function, and call it.
void(*)(void) mean a pointer to function, that gets no arguments, and return void.
If you cast 0x3D7C80 to that type, and call it, you basically call the function that its address is 0x3D7C80.
This is not an answer (that has already been done satisfactorily), but some advice:
I would suggest the following method instead:
typedef void (*tVOID_ROMFUNCTION_VOID)( void ) ;
tVOID_ROMFUNCTION_VOID Device_cal = (tVOID_ROMFUNCTION_VOID)0x3D7C80 ;
Device_cal() ;
That way you can create any number of global function pointers on initialisation while the calls look like normal statically linked functions. And you avoid confusing pre-processor macros voodoo at the same time.
By creating different function-pointer types with different signatures, the compiler will be able to perform some parameter type checking for you too.
The symbol is pasted in which creates a temporary (un named ) pointer to a function at a fixed memory location and then calls it via dereferencing.

Resources