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 (e.g. 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 e.g. 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).
size_t is more appropriate returned value for strlen rather than int
__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
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]
Related
There may or may not be a duplicate to this question, although I tried to find one but everyone's answer seemed to only be referring to the declaration/prototype. They specify that a definition void foo() { } is the same as void foo(void) { }, but which way should I actually use? In C89? In C99? I believe I should start using void foo(void); for my prototype declarations, but is there any difference at all if I use void or not for the definition?
They are different, void foo(void) declares foo as a function that takes NO argument, and returns nothing.
While for void foo(), the function foo takes UNSPECIFIED number of arguments, and returns void.
You should always use the first one for standard conforming C.
They are semantically different
Given the following functions:
void f(void);
void g();
It is a compile-time error to call f with arguments:
error: too many arguments to function "f"
However, that declaration of g means it takes an unspecified number of arguments. To the compiler, this means it can take any number of arguments, from zero to some implementation-defined upper bound. The compiler will accept:
g();
g(argument);
g(argument1, argument2, ... , argumentN);
Essentially, because g did not specify its arguments, the compiler doesn't really know how many arguments g accepts. So the compiler will accept anything and emit code according to the actual usage of g. If you pass one argument, it will emit code to push one argument, call g and then pop it off the stack.
It's the difference between explicitly saying "no, I don't take any arguments" and not saying anything when questioned. Remaining silent keeps the issue ambiguous, to the point where the statement which calls g is the only concrete information the compiler has regarding which parameters the function accepts. So, it will emit machine code according to that specification.
Recommendations
which way should I actually use?
According to the SEI CERT C Coding Standard, it is recommended to explicitly specify void when a function accepts no arguments.
The article cites, as the basis of its recommendation, the C11 standard, subclause 6.11.6:
The use of function declarators with empty parentheses
(not prototype-format parameter type declarators)
is an obsolescent feature.
Declaring a function with an unspecified parameter list is classified as medium severity. Concrete examples of problems that may arise are presented. Namely:
Ambiguous Interface
Compiler will not perform checks
May hide errors
Information Outflow
Potential security flaw
Information Security has a post exploring not just the security but also the programming and software development implications of both styles.
The issue is more about quality assurance.
Old-style declarations are dangerous, not because of evil programmers,
but because of human programmers, who cannot think of everything
and must be helped by compiler warnings. That's all the point of function
prototypes, introduced in ANSI C, which include type information for
the function parameters.
I'll try to answer simply and practically.
From the practice and reference I'm familiar with, c89 and c99 should treat declaration/definition/call of functions which take no arguments and return no value equally.
In case one omits the prototype declaration (usually in the header file), the definition has to specify the number and type of arguments taken (i.e. it must take the form of prototype, explicitly void foo(void) for taking no arguments)
and should precede the actual function call in the source file (if used in the same program). I've always been advised to write prototypes and decently segmented code as part of good programming practice.
Declaration:
void foo (void); /*not void foo(), in order to conform the prototype definition !*/
Definition:
void foo (void) /*must match its prototype from the declaration !*/
{
/*code for what this function actually does*/
return;
}
Function call from within main() or another function:
...
foo();
...
Yes, there is a difference. It is better to define functions like void foo(void){} cause it will prevent passing any arguments to function in compilation time with error like:too many arguments to function 'foo'
EDIT: If you want to add such compiler's validation for existing code, this probably can be done changing prototypes in the headers. Without changing the function definitions. But it looks awkward IMHO. So for newly created programs (as pointed by skillful commentators above) it's better to make definition and declaration match verbose, and this is bad and ancient practice to declare and define with empty parentheses
In every C program I had seen, there will be the main() function. Unlike in other languages, such as Java and C++, it has no data type before it. In C++ and Java there will at least be a void with main(), if not some other data type.
Why does main() have no data type with it in C?
Also, in Java the constructor has no data type used with it. Is it possible to return any value if no data type is used before functions? Or by default, can they return any value?
It's user-defined: you define it in each program. If it were a library function, you wouldn't define it, because the library would define it for you.
(As an exception to this, the Unix libraries libl and liby, the support libraries for Lex and Yacc, actually define main; the idea is that you define a bunch of functions with standard names and you get a default main that calls these functions. You can override their main, though. Apparently Windows compilers do something similar.)
main() is a user-defined function.
Standard clearly states that it is a user defined function:
C11: 5.1.2.2.1 Program startup
The function called at program startup is named main. The implementation declares no
prototype for this function. It shall be defined with a return type of int and with no
parameters:....
main() is always user defined, and can be prototyped in many ways (although some will argue that point)
(edited)
main(void){/*User defined content*/} // K&R implied `int` return type
void main(void){/*User defined content*/} //yeah, yeah, I know
int main(void){/*User defined content*/ return 0;} //commonly used
int main(int argc, char *argv[]){/*User defined content*/ return 0;} //commonly used
I use a C99 implementation of a C compiler. While it very explicitly notifies of any warning or error for illegal or nefarious syntax, It did not flag the following scenario:
So, while it is not strictly conforming, it is evidently not illegal.
I'm trying to read a project documentation. Under the title Prototype, I'm having this code :
VisionAPI_RETURN VisionAPI VisionInterf_ImageAttach(
VisionAPI_HANDLE ImageHandle ,
uint32_t NumImages
);
The project's interfaces will be build in C, when the functions will be in C++.
When reading the documentation, I read prototype, so I supposed it is "functions prototypes". When reading more, I find the author sometimes using the term "function" and sometimes "interface". I know how to make an interface in C++ but not in C.
So is the code above about interface or function prototype?
Otherwise, how to create an interface in C language? Is it by creating structure (struct) ?
I hope my question is not stupid. I'm a Java developer, and a C/C++ simple student.
This declares the function, without providing an implementation (the definition). So, you could say this is an interface. You just tell the compiler: "Hey, there is a function with the name VisionInterf_ImageAttach" so it doesn't complain when you call it. More about declaration vs. definition.
This, of course depends on what VisionAPI_RETURN and VisionAPI resolve to, assuming they are macros.
There is no such thing in C language as an interface: in addition to primitive types and pointers, the language supports structs and functions; that's all you have to work with.
Your code shows an example of a forward declaration of a function. Interfaces to C modules consist of multiple such declarations, along with declaration of structs that these functions use.
(Adding to the already useful info given by #bitmask and #dasblinkenlight)
In C a function prototype is, roughly, the declaration of a function signature, i.e. the declaration of the function name, return type and parameter list types (i.e. the types of the parameters the function accepts, in their respective order).
Therefore, in a sense, the prototype of a function can be viewed as the interface of the function towards client code (in this case the term interface is used in a general way, unlike what it means in OOP and Java in particular).
As a simpler example, suppose you defined a function like this:
int MyFunc( double x, char * z )
{
// function body code
}
then its prototype would be:
int MyFunc( double x, char * z );
or even
int MyFunc( double, char * );
since parameter names are optional in function prototypes.
There is no mechanism in C for creating an equivalent replica to Java interfaces, although often programmers refer to specially crafted C header files as "interfaces". These header files are filled with function prototypes and other declarations that represent the "interface" of the library they belong toward client code.
Therefore client code can #include those header files to access the facilities offered by the library without knowing its implementation (here is the "interface" thing), which usually is resolved at link time (or at run-time if dynamic linking is involved).
Edit (to answer a comment)
What you see before function name is probably some macro trick. Since I don't know what's the context I can only guess. The two identifiers VisionAPI_RETURN VisionAPI are most probably defined as macros. From their names I guess that the first expands to the actual return type, while the second could be either an empty macro (usually used to mark some category of declarations) or expands to some compiler-specific keyword combination, usually used to declare the function low-level calling convention.
For example, somewhere there could be these macro definitions:
#define VisionAPI_RETURN int
#define VisionAPI
so that, after the preprocessor has finished its work, the compiler will see this:
int VisionInterf_ImageAttach(
VisionAPI_HANDLE ImageHandle,
uint32_t NumImages
);
Another example - if those macros are defined like this:
#define VisionAPI_RETURN struct MyReturn
#define VisionAPI __stdcall
then the prototype will be expanded like this:
struct MyReturn __stdcall VisionInterf_ImageAttach(
VisionAPI_HANDLE ImageHandle,
uint32_t NumImages
);
In this case the return type would be struct MyReturn, while the __stdcall keyword would indicate the "stdcall" calling convention (the __stdcall keyword is used by Microsoft compilers). This resulting syntax is an extension to standard C syntax (many compilers have some kind of such extensions).
Perhaps this is just for showing. While reading K&R, the beginning of 1.7 Functions shows an example of a power function. The second line of code declares int power(int m, int n);
Why is the first argument, n, named differently than the first argument, base, in the source of the function:
int power(int base, int n)
{
...
}
Is this simply to show that the names do not need to be the same? And should this practice be avoided? Why or why not?
The types, and not the names, are what is important in the prototyped declaration. Some people omit the parameter names in the declaration; some use more descriptive names in the declaration (because people may need to read them in the header) than in the function definition. The opposite appears to be the case here; the name in the definition is more meaningful than in the declaration.
It is purely stylistic. I normally reckon to use the same names in declaration and definition, but sometimes the name needed for the definition (to explain the argument) is too verbose for comfortable use in the function definition.
See Stroustrup's "Design and Evolution of C++" for a discussion of why named parameters are not a part of C++. Yes, that's C++, but the arguments there (primarily unnecessary coupling between declaration and definition) apply to C too.
What the ... argument means in the declaration static void info(const char *fmt,...) ?
It's part of an C library I recently started to use. Sorry if it's basic C stuff but I never saw that before and google is not so verbose about ... !
It means variable arguments, which means the compiler will accept and compile calls to it with any arguments. Usually their types are indicated by values in preceeding arguments.
It takes a variable number of arguments in your method. I found this article explaining the details. It gets very complicated very quickly as you can see.
It is variable argument (Variadic function). It is just like printf.
int printf(const char *format, ...)
For more info, check this.
If a functions last argument is written as ... that means that the function takes arbitrarily many arguments (of arbitrary types as far as the compiler concerned - the function may of course require specific types, but the compiler has no way of enforcing those types).
These arguments can then be accessed using the va_* set of functions from stdarg.h.