I recently came across a strange syntax in C program.
struct connector_agent_api{
bool (*receive)(slot *s, uint8_t *data, uint8_t length);
}
Is "receive" a function pointer?
If it is a function pointer, why does it have named arguments? Should it be like the following one?
bool (*receive)(slot *, uint8_t *, uint8_t);
It certainly compiled and being used in a library. I searched on internet a lot and tried to justify this kind of syntax. I still don't know why this thing can be compiled... :(
The names of arguments in a function pointer are optional, just as the names of arguments in a function declaration are optional. This is because parameter names if given are not used, so both formats are allowed.
In section 6.7.6.3 of the C standard regarding Function Declarators, which includes both function prototypes and function pointers, paragraph 6 states:
A parameter type list specifies the types of, and may
declare identifiers for, the parameters of the function.
The only place where function parameters require a name is in the actual definition of a function.
For a function definition, Section 6.9.1p5 states:
If the declarator includes a parameter type list, the
declaration of each parameter shall include an identifier, except
for the special case of a parameter list consisting of a single
parameter of type void , in which case there shall not be an
identifier. No declaration list shall follow.
What makes you think it is a strange syntax? It is a valid declaration as per C standard. The fact that the parameters are named is irrelevant. The naming of such parameters is optional in this case. It can be really helpful if you or someone else is using an IDE because it could display the complete prototype upon using the function pointer to call the function and thus give a hint to the coder about the arguments to be supplied.
Related
If I have this prototype:
int bar(int);
for the compiler I'm declaring the identifier bar.
If I have this definition:
int bar(int a) {};
for the compiler I'm defining the identifier bar.
Generally speaking a definition make a storage allocation for an object but:
is it also true for the function declaration? Also in this case there is no storage allocated?
what's the storage allocated for function definition and when it's allocated?
P.S.
The C specification when says about declaration or definition says of their relatively of an identifier (i.e. the declaration of an identifier...)
But I've also read text where is said the declaration of a variable.
So is there some difference or is only a "double-way" to say about one meaning?
In case of function, storage allocation is done when a function called first time. Definition itself doesn't make a storage allocation.
You should also note that, making function body empty is valid when the return type of function is void. Therefore, compiler should raise a warning against
int bar(int a) {};
[Warning] control reaches end of non-void function [-Wreturn-type]
[Warning] ISO C does not allow extra ';' outside of a function [-pedantic]
Function declaration helps the compiler to check whether the call you make for the function obeys the same signature or not, for syntactical correctness in terms of return type, number and type of arguments and order of arguments too. A function definition is required by the linker for cross-referencing the call (use) and the definition.
When you declare a function, no storage is allocated, when you define a function, function created on relocatable reloadable address space, size depends on the machine language translation of the function, varies from platform to platform
In the C standard, every definition is also a declaration, and a function is not an object (I just mention it here, because many people use different terminologies, and I’m not sure which convention you use, I’ll use the terminology of the standard, as that’s common on SO).
For the standard (that is, in the abstract machine), a function takes no storage. The term “definition” is defined in C11 (n1570) 6.7 p5
A declaration specifies the interpretation and attributes of a set of identifiers. A definition of an identifier is a declaration for that identifier that:
- for an object, causes storage to be reserved for that object;
- for a function, includes the function body;*)
- for an enumeration constant, is the (only) declaration of the identifier;
- for a typedef name, is the first (or only) declaration of the identifier. [slightly different from C99, where redefining typedefs isn’t allowed]
*) Function definitions have a different syntax, described in 6.9.1.
The standard uses the term “variable” only in non-normative parts like footnotes (as a noun; it’s used in normative parts as an adjective, as in “variable-length array”).
For the term “identifier”, see ibid. 6.4.2.1,
(2) An identifier is a sequence of nondigit characters (including the underscore _, the lowercase and uppercase Latin letters, and other characters) and digits, which designates one or more entities as described in 6.2.1.
and ibid. 6.2.1 p1
An identifier can denote an object; a function; a tag or a member of a structure, union, or enumeration; a typedef name; a label name; a macro name; or a macro parameter. The same identifier can denote different entities at different points in the program. A member of an enumeration is called an enumeration constant. Macro names and macro parameters are not considered further here, because prior to the semantic phase of program translation any occurrences of macro names in the source file are replaced by the preprocessing token sequences that constitute their macro definitions.
For sake of completeness, a function prototype is a declaration; old-style declarations and old-style definitions are non-prototype declarations.
What it Means to Declare Something in C and C++
When you declare a variable, a function, or even a class all you are doing is saying: there is something with this name, and it has this type. The compiler can then handle most (but not all) uses of that name without needing the full definition of that name. Declaring a value--without defining it--allows you to write code that the compiler can understand without having to put all of the details. This is particularly useful if you are working with multiple source files, and you need to use a function in multiple files. You don't want to put the body of the function in multiple files, but you do need to provide a declaration for it.
So what does a declaration look like? For example, if you write:
int func();
This is a function declaration; it does not provide the body of the function, but it does tell the compiler that it can use this function and expect that it will be defined somewhere.
What it Means to Define Something in C and C++
Defining something means providing all of the necessary information to create that thing in its entirety. Defining a function means providing a function body; defining a class means giving all of the methods of the class and the fields. Once something is defined, that also counts as declaring it; so you can often both declare and define a function, class or variable at the same time. But you don't have to.
For example, having a declaration is often good enough for the compiler. You can write code like this:
int func();
int main()
{
int x = func();
}
int func()
{
return 2;
}
Since the compiler knows the return value of func, and the number of arguments it takes, it can compile the call to func even though it doesn't yet have the definition. In fact, the definition of the method func could go into another file!
You can also declare a class without defining it
class MyClass;
Code that needs to know the details of what is in MyClass can't work--you can't do this:
class MyClass;
MyClass an_object;
class MyClass
{
int _a_field;
};
Because the compiler needs to know the size of the variable an_object, and it can't do that from the declaration of MyClass; it needs the definition that shows up below.
In a function with variable arguments, we initialize an object of type va_list ,'ap' with the function va_start() as:
void va_start(va_list ap, parmN);
I don't understand
1.what type of objects can be passed as parMN(last known parameter). I've done with examples of passing integers, strings with format specifiers, structures etc.
2. How the parMN describes the following optional parameters.
The C standard says that va_start() is actually a macro, not a function, so it can do things a function couldn't. The details are highly implementation dependent but you could imagine that it takes the address of parmN to determine the stack address of the next parameter. There's no need for va_start() to know about the types of the following parameters because that information is passed to va_arg(), which is another macro.
I was recently reading about the usage of const keyword as function arguments in C and the way to use that has been mentioned in When and for what purposes should the const keyword be used in C for variables and been accepted as correct answer. In this post, one point mentions that
Never use const in a function prototype for a parameter passed by
value. It has no meaning and is hence just 'noise'.
I used this way and it works for me but I am not sure why that is a noise for parameters passed by value and yet not a noise for the parameters passed by reference (more aptly the pointer values in C as there is not concept of pass by value and pass by reference in C). So, by this explanation when I pass a pointer as a function argument and use a const keyword; I have to do this for both the declaration in the header file and the definition in the C file but I need not use the const keyword for a non-pointer argument in the declaration (header file) and only use it while defining the function in the C file.
Any explanations?
The statement you quote is a bit misleading, because in C, all arguments are passed by value.* I suppose it is trying to distinguish between the arguments themselves and, for the special case of arguments that are pointers, their referents.
In any event, the point is that const-qualifying a function parameter in the function declaration conveys no information whatever to callers. Regardless of such qualification, the function cannot modify the caller's copy of any argument anyway, because arguments are passed by value.
*Note, however, that arrays are never passed at all. In function call expressions, as in most contexts, array values "decay" to pointers, and those pointers are passed by value. This produces an effect similar, but not identical, to what you would have if arrays were passed by reference.
It's the rule. If in the declaration of a function, you don't mark your parameters const, you can mark them const in the definition.
Some folk like to mark as many parameters const as possible in the definition since it can guard against unintentional modification of the function parameters; which could introduce bugs. Personally I don't do this but plenty of houses (including a large bank headquartered in Scotland) insist on the style.
Posting this here because I wrote it for a code review and figured it was worth preserving:
Adding const to a value-type parameter in the function declaration is useless. The caller won't care whether the parameter is modified or not because the caller's data won't be affected in any way. The parameter is a separate object than the argument that was passed in, constructed by copy [or by move for rvalue arguments into move-constructible parameters (since C++11)].
Adding const to a value-type parameter in the function definition marks the separate, function-local object as const. This is essentially the same as marking a local variable 'const', and value-type parameters should usually be treated as local variables when determining whether the value-type should be const.
The C & C++ standards demand that compilers & linkers be smart enough to match the following declaration with its definition:
// Declaration
void Foo(int bar);
// Definition
void Foo(const int bar){
printf("%i", bar);
}
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
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.