Use of (apparently) empty C function - c

Can anyone comment on the point of the following function, which appears to do not very much:
// Returns stored values
int getDetails(const int param1[],
int* param2,
int* param3,
int* param4)
{
(void)param1;
(void)param2;
(void)param3;
(void)param4;
return 0;
}
The comment is actually there with the code. I'm thinking it must be some kind of odd stub but it is being called and I'm racking my brains to try to imagine what I'm missing.
My best hunch so far is that the function has been deprecated but not removed and the (void)param is to avoid compiler warnings about unused variables.

Statements like (void)param1; are typically used to suppress warnings about unused function parameters. (As an aside, in C++ you could also comment out or remove the parameter names.)
You're correct that the function does nothing. If other code doesn't create a pointer to it, you could safely remove it.

It's an empty function. Casts to void suppress warnings about unused parameters.
Such functions are often used when a function must be called unconditionally or a valid function pointer must be provided, but really the function has nothing to do.
I have a few such functions in my compiler's code generator. There are two code generators actually, one for x86 and the other for MIPS. I compile and link one or the other, never both at the same time.
The code generators are different internally but have the same external API. So, some functions specific to one CPU have some work to do while the same functions for the other have nothing to do. Logically, some of them are empty since there's nothing to do.

My guess (opinion - sorry!) that it could be a stub as you say. If you have a function that takes one or more function pointers to achieve something and it does not allow for a NULL (don't bother with this) then you have to provide something for it to call.
The casts are probably to avoid the "unused parameter" warning.

You're right, it has no point.
All it does is explicitly ignore the arguments by evaluating them and casting the result to (void), and return 0.
Is the return value being used in the context of the call? The best approach is of course to remove the call and replace it with a 0 if the return value is being used, and test the program.

Some Compilers shows error/warning when you are not using the arguments passed to it , to avoid that mention that like it in your code . If the function is not called any where or not assigned to any function pointers , you can remove it as it is not doing anything specific

Related

Do gcc function attributes affect function pointers?

Do gcc's function attributes extensions have any effect when used on the type of function pointers?
The function attributes can be used when declaring the type of function pointers but at least some of them seem to have no effect.
https://stackoverflow.com/a/28740576/1128289
The gcc documentation itself does not address this issue.
Very generally, the C standard basically says that handling an object over a pointer whose type is not aligned with the type of the object itself generates undefined behaviour - There are many exceptions to this general rule, but, apparently, none of them seems to apply to your case.
That means we're moving on very unsafe grounds here, in the first place.
First, you need to distinguish function attributes into two classes:
Function attributes that actually change something in the behavior or location of the function itself like aligned or interrupt- A function that is not attributed that way will not change its inner code once you declare a pointer to it interrupt, for example (the code that is generated for the function would need to dynamically change - for example, a "return from interrupt" instruction replaced by a "return normally" one - depending on along what type of pointer it would have been called). This is obviously not possible.
Function attributes that tell the calling code something about the behaviour that can be expected from the function - like noreturn or malloc, for example. Those attributes sometimes might not modify the function code itself (you'll never know, however...), but rather tell the calling code something about assumptions it can make in order to optimise. These assumptions will affect the calling function only and thus can be triggered by tweaking a pointer (you don't even need a pointer to do that, a modified function prototype should suffice - for the language, that would actually turn out to have the same effect). If you tell the compiler it can make such assumptions and those turn out not to be true, this will, however, lead to all sorts of things go wrong. After all, C makes the programmer responsible for making sure a pointer points to the right type of thing.
There are, however, function attributes that actually restrict the amount of assumptions a calling function would be allowed to make (the most obvious would be malloc that tells calling code it returns yet untyped and uninitialized memory). Those should be relatively safe to use (I do, however, fail to come up with a use case atm)
Without very detailed knowledge on what belongs into (1) or (2) above, and what exactly a function attribute might affect in both called and calling code (which would be very difficult to achieve, because I don't recall to ever have seen that documented in detail), you thus will not be able to decide whether this pointer tweaking actually is possible and what side effects it might generate.
Also, in my opinion, there is not much of a difference between tweaking a pointer to a function and calling an external function with a (deliberately) wrong prototype. This might give you some insight on what you are actually trying to do...

Default parameters for a function in C --

I'm a beginner, so apologies if I overstep any rules. Here's my question.
I am using a GCC compiler on Codeblocks and there is something peculiar I noticed with a particular snippet of code. I'm hoping someone could shed some light on this.
int main()
{
Tree *t;
//some operations on the tree
traverse();// No parameter is passed here.
...
}
void traverse(Tree *t)
{
..
}
In the following code, the function traverse() executes correctly. My question is why? I'm not sure about this, but if a function is not declared, its default type becomes int. Now, the compiler not only suppressed an error at the time of compilation, it also correctly supplied the parameter 't' to the function traverse().
Is this because of an intelligent compiler design?
So in general: the question I have is - what behavior does the compiler default to if it encounters a method that has not yet been declared? And more importantly, how does it "know" which parameter I wanted to pass?
For all you know, I could have had three instance of "Tree *": t1, t2 and t3. Which one would the compiler pass then?
I tried looking around on Google, but have yet to locate a definitive source.
Thank you for your time. :)
The function is looking for its argument on the stack. The function doesn't know that the argument it's expecting isn't actually there.
By chance, the thing on the stack where it's looking for the argument is the local variable t in your main() function. If you had more local variables inside main(), then one of them would be misinterpreted as the function's argument, and things would go badly wrong.
So, it's working purely by chance.

Unknown C expression

I ran across the following line in an example program, and don't know what it is. I imagine it's a function call, but am not sure:
(void) pthread_mutex_init(&bottleneck, &mxattr);
If it is a function call, why is it preceded with (void)? I've never seen that before. Here's the line in more context:
attr_init(pthread_process, pthread_scope, stacksize);
(void) pthread_mutex_init(&bottleneck, &mxattr);
barrier_init(&setup_barrier, (2 * ntables) + 1);
Thanks for the help. The entire program is from this Solaris whitepaper (Appendix D)
It is a normal function call. The (void) part just indicates that the function returns a value and nothing will be done with it. To remove any warnings of about unused return values.
See casting unused return values to void.
POSIX Threads
The specific call - pthread_mutex_init - returns int. The cast to void is probably done to avoid specific warning about the return value being ignored during either compile time or a static code analysis.
Update: As #Jack Kelly commented on another answer, any good static analysis tool would simply ignore this cast and continue issuing the warning. Static analysis should be controlled through separate specific annotations, not by using language constructs that can affect the compiler output.
This is a function call with explicit casting of the result to void. This is just a development style to hint both compiler and those who read this code that function call is actually returning something that is intentionally ignored. In this example, pthread_mutex_init function returns integer. Some compilers will give you a warning if you call a function marked with warn_unused_result attribute.
Yes it is a function call. The function pthread_mutex_init() initializes a mutex used to prevent multiple threads clobberring some shared resource.
The function returns an int, the (void) is flagging that we are intentionally ignoring the return value. It stops the compiler complaining about unused return values.

Need for prefixing a function with (void)

I recently came across a rather unusual coding convention wherein the call for a function returning "void" is prefixed with (void).
e.g.
(void) MyFunction();
Is it any different from the function call like:
MyFunction();
Has it got any advantage or is it yet another needless but there coding convention of some sort?
Some functions like printf() return a value that is almost never used in real code (in the case of printf, the number of characters printed). However, some tools, like lint, expect that if a function returns a value it must be used, and will complain unless you write something like:
int n = printf( "hello" );
using the void cast:
(void) printf( "hello" );
is a way of telling such tools you really don't want to use the return value, thus keeping them quiet. If you don't use such tools, you don't need to bother, and in any case most tools allow you to configure them to ignore return values from specific functions.
No, there isn't any difference -- what's being cast to void is the return value of the function.
I'd say it could make sense of you wanted to make explicit you're not using the return value (you're calling it for the side effects), but as the function already has void return, it doesn't make much sense.
If the function returns something the void could avoid (!) a warning (indeed in no way I was able to make gcc warn me that the return value is lost) on some compilers (or lint tools); but more importantly, it makes clear that a return value is "thrown" away purposely (and not by mistake).
acedemically: a "function" always returns something, else it would be a procedure. So the Author of this code wants to say "i know this naming is wrong, but i will no change the name, so i make this disturbance visible"
Has it got any advantage or is it yet another needless but there coding convention of some sort?
No difference. It is a quite common convention e.g. in software testing to highlight the fact that in context the function return, if any, is safe to be discarded.
In HPUX man pages it is quite common in example code to see a cast to void to get around lint warnings.
fprintf(mystream, "%s\n", "foo");
vs.
(void)fprintf(mystream, "%s\n", "foo");
That may be where the author of the code is coming from. IMO, this is not a great idea because most of the sprintf family, for example, call malloc. malloc will fail when there is not enough memory. SIGINT also causes the underlying write() syscall to interrupt and not write all of the buffer, for printf() family members.

Function pointer cast to different signature

I use a structure of function pointers to implement an interface for different backends. The signatures are very different, but the return values are almost all void, void * or int.
struct my_interface {
void (*func_a)(int i);
void *(*func_b)(const char *bla);
...
int (*func_z)(char foo);
};
But it is not required that a backends supports functions for every interface function. So I have two possibilities, first option is to check before every call if the pointer is unequal NULL. I don't like that very much, because of the readability and because I fear the performance impacts (I haven't measured it, however). The other option is to have a dummy function, for the rare cases an interface function doesn't exist.
Therefore I'd need a dummy function for every signature, I wonder if it is possible to have only one for the different return values. And cast it to the given signature.
#include <stdio.h>
int nothing(void) {return 0;}
typedef int (*cb_t)(int);
int main(void)
{
cb_t func;
int i;
func = (cb_t) nothing;
i = func(1);
printf("%d\n", i);
return 0;
}
I tested this code with gcc and it works. But is it sane? Or can it corrupt the stack or can it cause other problems?
EDIT: Thanks to all the answers, I learned now much about calling conventions, after a bit of further reading. And have now a much better understanding of what happens under the hood.
By the C specification, casting a function pointer results in undefined behavior. In fact, for a while, GCC 4.3 prereleases would return NULL whenever you casted a function pointer, perfectly valid by the spec, but they backed out that change before release because it broke lots of programs.
Assuming GCC continues doing what it does now, it will work fine with the default x86 calling convention (and most calling conventions on most architectures), but I wouldn't depend on it. Testing the function pointer against NULL at every callsite isn't much more expensive than a function call. If you really want, you may write a macro:
#define CALL_MAYBE(func, args...) do {if (func) (func)(## args);} while (0)
Or you could have a different dummy function for every signature, but I can understand that you'd like to avoid that.
Edit
Charles Bailey called me out on this, so I went and looked up the details (instead of relying on my holey memory). The C specification says
766 A pointer to a function of one type may be converted to a pointer to a function of another type and back again;
767 the result shall compare equal to the original pointer.
768 If a converted pointer is used to call a function whose type is not compatible with the pointed-to type, the behavior is undefined.
and GCC 4.2 prereleases (this was settled way before 4.3) was following these rules: the cast of a function pointer did not result in NULL, as I wrote, but attempting to call a function through a incompatible type, i.e.
func = (cb_t)nothing;
func(1);
from your example, would result in an abort. They changed back to the 4.1 behavior (allow but warn), partly because this change broke OpenSSL, but OpenSSL has been fixed in the meantime, and this is undefined behavior which the compiler is free to change at any time.
OpenSSL was only casting functions pointers to other function types taking and returning the same number of values of the same exact sizes, and this (assuming you're not dealing with floating-point) happens to be safe across all the platforms and calling conventions I know of. However, anything else is potentially unsafe.
I suspect you will get an undefined behaviour.
You can assign (with the proper cast) a pointer to function to another pointer to function with a different signature, but when you call it weird things may happen.
Your nothing() function takes no arguments, to the compiler this may mean that he can optimize the usage of the stack as there will be no arguments there. But here you call it with an argument, that is an unexpected situation and it may crash.
I can't find the proper point in the standard but I remember it says that you can cast function pointers but when you call the resulting function you have to do with the right prototype otherwise the behaviour is undefined.
As a side note, you should not compare a function pointer with a data pointer (like NULL) as thee pointers may belong to separate address spaces. There's an appendix in the C99 standard that allows this specific case but I don't think it's widely implemented. That said, on architecture where there is only one address space casting a function pointer to a data pointer or comparing it with NULL, will usually work.
You do run the risk of causing stack corruption. Having said that, if you declare the functions with extern "C" linkage (and/or __cdecl depending on your compiler), you may be able to get away with this. It would be similar then to the way a function such as printf() can take a variable number of arguments at the caller's discretion.
Whether this works or not in your current situation may also depend on the exact compiler options you are using. If you're using MSVC, then debug vs. release compile options may make a big difference.
It should be fine. Since the caller is responsible for cleaning up the stack after a call, it shouldn't leave anything extra on the stack. The callee (nothing() in this case) is ok since it wont try to use any parameters on the stack.
EDIT: this does assume cdecl calling conventions, which is usually the default for C.
As long as you can guarantee that you're making a call using a method that has the caller balance the stack rather than the callee (__cdecl). If you don't have a calling convention specified the global convention could be set to something else. (__stdcall or __fastcall) Both of which could lead to stack corruption.
This won't work unless you use implementation-specific/platform-specific stuff to force the correct calling convention. For some calling conventions the called function is responsible for cleaning up the stack, so they must know what's been pushed on.
I'd go for the check for NULL then call - I can't imagine it would have any impact on performance.
Computers can check for NULL about as fast as anything they do.
Casting a function pointer to NULL is explicitly not supported by the C standard. You're at the mercy of the compiler writer. It works OK on a lot of compilers.
It is one of the great annoyances of C that there is no equivalent of NULL or void* for function pointers.
If you really want your code to be bulletproof, you can declare your own nulls, but you need one for each function type. For example,
void void_int_NULL(int n) { (void)n; abort(); }
and then you can test
if (my_thing->func_a != void_int_NULL) my_thing->func_a(99);
Ugly, innit?

Resources