tags:

views:

420

answers:

4

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?

+2  A: 

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();

lothar
Roboprog
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.
Johannes Schaub - litb
+9  A: 

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
Johannes Schaub - litb
The __ARGS was not the original question. The "static void nv_operator __ARGS((cmdarg_T *cap));" is a forward declaration.
lothar
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.
Johannes Schaub - litb
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).
hasen j
oh ok. never mind then :)
Johannes Schaub - litb
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).
lothar
actually, I know what a forward declaration is, I'm not *that* n00bish :)
hasen j
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 :-)
lothar
turned out the trick is to "slaughter" the definition to 3 lines so that you can't find it by simply grepping! >:[
hasen j
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.
Johannes Schaub - litb
+1  A: 

Its hard to find because of how it is defined:

nv_operator(cap)

appears on a line by itself.

ojblass
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 is
hasen j
and btw who down-voted it? strategic down-voting?
hasen j
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.
ojblass
+1  A: 

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.

Tom