I'm looking at the vim source code, specifically the file normal.c, and I see this function nv_operator
being used, but it's not defined anywhere (I grepped the entire src directory)
It's only declared as:
static void nv_operator __ARGS((cmdarg_T *cap));
I've looked up the definition of __ARGS but it's just ... nothing (pretty much)
in vim.h:
#define __ARGS(x) x
So what could be going on? Is this some kind of C
technique to create a dummy function or something?
-
It's simply a forward declaration, so that the function is known to the C compiler (and can be used (called from other functions)) before it's actually defined (in line 8247). The actual formatting of the definition (which includes newlines) makes it hard to grep for it's existence.
Don't get distracted by the __ARGS macro. It's only a compatibility macro for the different function declaration syntaxes of K&R C vs. ANSI C.
In ANSI C a function declaration must look like this:
int getopt(int, char * const *, const char *);
In the (older) Kernighan and Ritchie C http://en.wikipedia.org/wiki/C_(programming_language)#K.26R_C
int getopt();
Roboprog : I was wondering when somebody was going to actually name "K&R" (instead of "some older versions") and "ANSI".Johannes Schaub - litb : non-prototype function declarations are still ANSI C conform. what's disallowed (in c99) is the implicit int rule and the implicit function declaration (function must be declared before used now) rule. -
There is a definition present here:
/* * Handle an operator command. * The actual work is done by do_pending_operator(). */ static void nv_operator(cap) cmdarg_T *cap; ....
That style of definition is using an identifier list for its parameters. The style is deprecated (obsolescent) but can still be used in C. The identifiers are named in the parameter list, and their type are named in declarations that immediately follow the function declarator but precede the functions body.
The
__ARGS
macro is there to handle compilers that don't know about prototypes for functions (the other form to declare parameters - with type and name combined directly in the function parameter list). It would then just emit no parameters at all in declarations, i think.Update: See this code in
vim.h
:#if defined(MACOS) && (defined(__MRC__) || defined(__SC__)) /* Apple's Compilers support prototypes */ # define __ARGS(x) x #endif #ifndef __ARGS # if defined(__STDC__) || defined(__GNUC__) || defined(WIN3264) # define __ARGS(x) x # else # define __ARGS(x) () # endif #endif
lothar : The __ARGS was not the original question. The "static void nv_operator __ARGS((cmdarg_T *cap));" is a forward declaration.Johannes Schaub - litb : Seen only one version of the question. He seems to ask about __ARGS and where the definition is. The issue with non-prototype functions is an important reason why the definition is difficult to find imho. A definition like "static void f(cmd *t) { .. } would have been way easier for him to find.hasen j : I never really asked about __ARGS .. just used it as a supplement to my arguments that nv_operator is not defined (because one could argue that __ARGS does some magic to make the definition work).Johannes Schaub - litb : oh ok. never mind then :)lothar : I know, that's why I pointed out that the answer to you question is that the construct is a "forward declaration". The fact that the actual definition includes newlines makes it so hard to find (grep).hasen j : actually, I know what a forward declaration is, I'm not *that* n00bish :)lothar : Never wanted to imlpy you don't know what a forward declaration is. just that it's the answer to your "So what could be going on? Is this some kind of C technique to create a dummy function or something?" question :-)hasen j : turned out the trick is to "slaughter" the definition to 3 lines so that you can't find it by simply grepping! >:[Johannes Schaub - litb : i found GNU coding guidelines generally put the return type and the function name on separate lines. so you can do this: "grep '^function_name'" and you will find the function definition very easily by that. -
Its hard to find because of how it is defined:
nv_operator(cap)
appears on a line by itself.
hasen j : I want to accept this answer (more than the other) because it's short and addresses my point directly, but it's somehow confusing in its own right because it doesn't mention where the definition ishasen j : and btw who down-voted it? strategic down-voting?ojblass : I am a bit of a simplicity nut... I look at the question and it says what could be going on? Well this is what is going on and why it seems like magic. I have seen stuff like this cost thousands of dollars in trouble shooting time. -
I am not too sure what is going on, but here are some hints to help you in your search:
First of all, the __ARGS macro seems to be there because there may be versions of C where you shouldn't include the args in the declaration of the functions (Notice that the macro is defined differently depending on other preprocessor symbols... the comments say it).
Secondly, searching for the function nv_operator may not be good enough. The function might be generated by macros and such, so you can't search for an explicit definition.... for example, maybe the "nv" prefix is added by the preprocessor.
Hope this helps.
0 comments:
Post a Comment