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.
Related
I am presently in a case where I need to call a lot of function pointers that has been extracted at runtime. The problem is that the arguments are unknown at compilation time.
But, at runtime I receive datas that allows me to know the arguments of the function and I can even store the arguments in a char* array. The problem is that I don't have a function pointer model to cast it into.
In high level language, I know there is function like "InvokeMethode(String name,Byte[] args)" that interpret the bytes array like arguments. Since reflection does not exist in C, I have no hope to see this with a function pointer.
One solution that I have in mind (and it's really bad), is to create a model of function pointer at compilation time that will cast in a "hardcoded way" the ptr to the right type to use like this:
void callFunc64Bits(void* funcPtr,long long args);
void callFuncVoid(void* funcPtr);
The problem is that I will have to create like 100 function like this that will cast the pointer correctly.
Is there a way to do it more efficiently?
Thank you very much!
This is a hard problem without, unfortunately, good or easy answers.
See this former SO question: Run-time parameters in gcc (inverse va_args/varargs)
See this C FAQ question: http://c-faq.com/varargs/invvarargs.html
See this collection of "wacky ideas" by the C FAQ list maintainer: http://c-faq.com/varargs/wacky.html
Addendum: see this former SO question: How to call functions by their pointers passing multiple arguments in C?
...which mentions "libffi": http://sourceware.org/libffi/
I am presently in a case where I need to call a lot of function pointers that has been extracted at runtime. The problem is that the arguments are unknown at compilation time.
But, at runtime I receive datas that allows me to know the arguments of the function and I can even store the arguments in a char* array. The problem is that I don't have a function pointer model to cast it into.
In high level language, I know there is function like "InvokeMethode(String name,Byte[] args)" that interpret the bytes array like arguments. Since reflection does not exist in C, I have no hope to see this with a function pointer.
One solution that I have in mind (and it's really bad), is to create a model of function pointer at compilation time that will cast in a "hardcoded way" the ptr to the right type to use like this:
void callFunc64Bits(void* funcPtr,long long args);
void callFuncVoid(void* funcPtr);
The problem is that I will have to create like 100 function like this that will cast the pointer correctly.
Is there a way to do it more efficiently?
Thank you very much!
This is a hard problem without, unfortunately, good or easy answers.
See this former SO question: Run-time parameters in gcc (inverse va_args/varargs)
See this C FAQ question: http://c-faq.com/varargs/invvarargs.html
See this collection of "wacky ideas" by the C FAQ list maintainer: http://c-faq.com/varargs/wacky.html
Addendum: see this former SO question: How to call functions by their pointers passing multiple arguments in C?
...which mentions "libffi": http://sourceware.org/libffi/
Before someone instantly marks this as a duplicate, let me say that I have spent a few hours searching for an answer to this (and read many similar S/O questions)
Here's the situation: I'm playing around with _Generic and trying to implement a dictionary structure which auto-casts upon retrieval. Let me explain (if you don't care, skip ahead to the bold header). From what I see, the go-to way to have a dictionary structure in which all values belong to the same field involves void pointers, which require the user to cast upon retrieval; here is an example:
struct C99_Dict *d = new_C99_Dict(); /* Creates a pointer to an empty dict
d: {} */
int i = 7;
put_in_c99_dict(d,"key",i); /* d: {"key": (void *)&i} */
...
// BAD: Will cast to i's address
int j = get_from_c99_dict(d,"key");
// BAD: Dereferencing void pointer
int k = *(get_from_c99_dict(d,"key"));
// GOOD: Will set l equal to 7
int l = *(int *)get_from_c99_dict(d,"key");
As one might imagine, after a while (especially once struct *s get thrown into the mix...although that's unchanged in my current project) your code ends up looking like something out of a Lisp textbook.
Using _Generic, however, I have managed to figure out a way to make an easier-to-use dictionary which auto-casts in such a fashion that the line
int j = get_from_c11_dict(d,"key");
becomes perfectly valid and works as one would expect (for builtins...structs still require manual casting). Changing the behavior of put_in_c11_dict based on the input type is easy enough, for the _Generic keyword does all of the heavy lifting. What is difficuly, however, is the notion of casting on the way out. This is because, in order for the dictionary struct to be well-defined, its value must be a consistent type (e.g. void*, as I have implemented). The problem with this, however, is that the type information is lost after the insertion function has processed the given input.
My initial (failed) attempt at a workaround for this was to make a dictionary struct of the following form:
typedef struct _dict_mem_struct{
union {
_Bool(*bool_get)(_dict_mem_struct*);
char(*char_get)(_dict_mem_struct*);
...
char *(*char_point_get)(_dict_mem_struct*);
void *(*void_point_get)(_dict_mem_struct*);
} get;
void *value;
} _dict_mem_t;
In hopes of (albeit perhaps foolishly so) being able to do the following in a _get helper macro definition:
#define _get(mem_struct) _Generic((mem_struct.get) ... )
Unfortunately, I then learned from gdb that mem_struct.get was of type union, so it was back to the drawing board. Eventually, I got something that worked. First, I added a char* field to the member structure which contained the original type. Then what I really needed was an inlined switch statement, since I had no prior indication of what the function signature would be. So, here's the hideous thing I did (is it technically invalid C? Maybe. Probably. I don't know. Nevertheless, GCC compiles it and it works, so I'm happy.)
#define IS_PFX(val,pfx) (!strcmp(val->pfx, pfx))
#define _get(valstruct) (IS_PFX(valstruct,"bool") ? boolval(valstruct) : IS_PFX(valstruct,"char") ? charval(valstruct) : ... : valstruct)
Yeah, I know; I'm probably going to hell for this. So, with that...
Here's my actual problem: When I compile this, it works, but gcc gets extremely upset with me. It gives me a bunch of errors such as
dict.c:203:75: warning: pointer type mismatch in conditional expression
#define PAIR(valstruct,str,fn,rst) (IS_PFX(valstruct,str) ? fn(valstruct) : rst)
From what I can gather, this means gcc is upset that these functions are all of different types. Nevertheless, as previously stated, the code works, so I would like to tell gcc to put a sock in it for specifically those warnings. The problem is that when I run gcc -fdiagnostics-show-option, those warning lines have no -W... flag after them. Furthermore, I have read through the gcc warning flag page, and nothing stands out as obvious to me which I could use to suppress these. Finally, the warnings still do not go away after adding the lines #pragma GCC diagnostic ignored "-Wall" and #pragma GCC diagnostic ignored "-Wextra". How can I get rid of these? Another solution I would be fine with is somehow turning off all warnings for specifically that file, since the reason I don't want them is so that I can integrate this into other projects without headache.
Thanks for any and all assistance. By the way, if there is some better way to do all of this, then please let me know. Regardless, I'm thinking I'll make a git repo for this once I've worked some of these kinks out, since I think it would be useful (if so, I'll update this post with a link).
gcc is probably right, you are mixing different pointer types in a ternary expression. So your design is most probably wrong. Have in mind that _Generic can't do miracles, the type system in C remains static, determined at compile time. It can only take care of type information that you pass to it in the first expression.
If you cast away type information to void*, store the pointer somewhere and try to retrieve it later, by definition _Generic can't help you. The context of the retrieval doesn't have the type information anymore, it might be called for such pointers that come from different places.
So in particular for a dictionary structure C can never know at the retrieval side, what type the original pointer had been. If you want to keep that information, you'd have to do that yourself and store that information along with the pointer.
BTW, already your question title is wrong: there is no such thing as a generic function in C. There are type generic function-like macros.
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
Folks, my professor has assigned us an assignment involving typing with arrays, pointers, and functions. Now, before you jump on my back with the whole "We aren't going to do your homework for you" thing, the answer to my question will not solve the problem. In fact, I've already taken my best guess at the answer. I am just curious to hear what you think about this.
Here is the C statement I was given:
double(*foo(double(*)(double,double[]),double))(double, ...);
Our problem involved describing the type of foo. My question is simply this: What on earth does this statement do? As far as I can read it, this is either one of the most obfuscated and unrealistic lines of code I've ever seen, or it's not actually valid C. Let me know what you think.
What you want to learn is the Clockwise Spiral Rule. Learning this will help you describe, in plain words, what any type in C is. Learn it well.
This will help a little
typedef RETURNTYPE (* POINTER_TO_FUNCTION_TYPE)(ARGTYPE1, ARGTYPE2)
C supports a type that is a pointer to function, and you can typedef one this way to simplify longer expressions based on it.
So, with this typedef, I could declare this function
POINTER_TO_FUNCTION_TYPE f(POINTER_TO_FUNCTION_TYPE g);
It's a function that takes a pointer to function and returns a pointer to a function. Without the typedef, imagine how that declaration would look.
According to my compiler (Visual Studio 2010) the statement does absolutely nothing. It compiles successfully, but there are no assembly instructions generated for it, so the debugger steps right over it. As for why it does nothing and what it really means - it would take someone with more knowledge of C than me to explain that.
I can figure out the type of foo using the clockwise/spiral rule, though - thanks, jer! It's easier if you reformat it a bit:
double
(
*foo
(
double(*)(double, double[]),
double
)
)
(double, ...);