简体   繁体   中英

Function Prototypes in C

Earlier today I was looking through various header files just to compare them to the ones I was making and noticed that they seem to declare their functions a bit differently.

For example here is the declaration for strlen from string.h :

extern size_t __cdecl strlen(const char *);

Upon doing some research I found that extern is for declaring a variable outside a function block. Is it best practice to declare my functions in header files with extern as well?

I see they use size_t which is unsigned long long here instead of int , I'm assuming that this is because it is more efficient for several reasons (eg the length of a string will never be a negative number) but is that the reason they use size_t here? Or am I missing the point completely?

Then finally I see __cdecl which I can't find much information on. What is __cdecl exactly? Should I be using it too?

And finally, I notice that in this declaration there is no variable name for the arguement being passed to strlen . I'm guessing that the reason for this is that this is not a function prototype, just a declaration, and the prototype is elsewhere. Why are there no variable names eg strlen(const char *str) in the declaration?

And my last question is what would the function prototype for strlen look like if this is just a declaration? My guess is something like:

size_t strlen(const char *str)

I am just asking because I want to learn and improve my code (assuming I am making function prototypes/declarations in a C file, and then just function declarations in a header file so that other C files can utilize them).

  1. size_t is more appropriate returned value for strlen rather than int
  2. __cdecl is a calling convention for a function. This signifies who sets up a stack for parameters, return value etc and who clears it. More reference: Calling convention
  3. While declaring a function, you don't really need parameter names. Just parameter type is sufficient.

Update for extern :

  • extern tells to compiler that the statement is just a declaration and not definition. So for functions prototypes, extern doesn't add any value as it already just a definition. Reference: C Extern

Hope this helps.

The extern keyword is redundant when declaring functions, since it is obvious it has to be defined somewhere else. The same is not true for variables where there would be no difference between a declaration and a definition without extern .

size_t is what strlen is defined to return. In your case it also seems like a 64-bit system, where theoretically a string can be larger that what can be stored in an int .

__cdecl is the calling convetion used when compiling the standard library. In case you should select a different calling convention for your program (using some compiler options), the precompiled library functions will still use the correct convention.

I most often name all the parameters in a function declaration, because it helps document what they are. Just int f(int, int, int, int) doesn't help me much, but is enough for the compiler. Therefore the names are optional.

About size_t as @Rohan said, it a type that used to hold size. it can't be negative for example. It's mainly because of some security issues. ( For example security vulnerability in getpeername in FreeBSD caused by using int instead of size_t )
And about cdecl this might help you ( It's from PC assembly book ) :

Borland and Microsoft use a common syntax to declare calling conventions . They add the cdecl and stdcall keywords to C. These keywords act as function modifiers and appear immediately before the function name in a prototype. For example, the function f would be defined as follows for Borland and Microsoft:

void __cdecl f ( int );

There are advantages and disadvantages to each of the calling conventions. The main advantages of the cdecl convention is that it is simple and very flexible. It can be used for any type of C function and C compiler. Using other conventions can limit the portability of the subroutine. Its main disadvantage is that it can be slower than some of the others and use more memory (since every invocation of the function requires code to remove the parameters on the stack).

The advantages of the stdcall convention is that it uses less memory than cdecl. No stack cleanup is required after the CALL instruction. Its main disadvantage is that it can not be used with functions that have variable numbers of arguments. [Like printf ]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM