What is the use of empty functions in embedded C? - c

I am working on an embedded project and in the source code of the project (which is in C) contains a function which is used to check whether the ethernet type is polling or interrupt.
We have a function as below
unsigned char mode(void);
unsigned char xmode(void)
{
if(mode())
return 1;
return 0;
}
The function mode() does not have a body. What will happen when the function mode() is called by the function xmode() ?

To extend on the previous answers.
That isn't an "empty" function, it is a prototype.
The compiler uses this to output object code for the functions you have the body for. It needs to be able to set up the function call properly and make sure it handles any conversions and the like. The object code will contain references to the function and the linker will replace these references with the correct value.
It also means that the compiler can do error checking for you and get more information than the linker could. Fun fact, the C standard used to allow implicit declaration of functions.
(This is simplified, for clarity.)

In the above code unsigned char mode(void); tells the compiler that the function mode() exist and it doesn't take any arguments but returns an unsigned char.
This doesn't really define the function. It only defines the way to call it. This thing is called a function prototype.
The function mode() is defined either later in this same file or in another file (possibly an assembly file).
One of the common uses of function prototypes is to implement recursion.
Consider functions a() and b(), each calling the other one, and defined in the same file:
void a()
{
b();
}
void b()
{
a();
}
When the compiler sees b() inside of a(), it does not have a slightest idea of what b() really is or what it's supposed to be. Obviously, if you change the order in which you define a() and b(), you will have the same problem, but now a() won't be known inside of b().
To fix that, you add a prototype:
void b();
void a()
{
b();
}
void b()
{
a();
}
Now the compiler will know what b() is (a function) and know how to call and use it.

This will either fail to link, or else there is a file that you're linking with that contains the actual mode() function.

Related

Declare global variable after function

Why do we need to declare global variables before function defining and declaring since we call this function after this variable declaration? Isn't it that compiler read line by line? I mean while calling the function compiler should know what's x.
void function()
{
x += 3
}
int x = 3;
int main(void)
{
function();
return 0;
}
And one more question. I know that we can define function after main function provided we declared this function before main. Then how does main function see these functions after main function? Does the compiler first read the whole file and then run main() or sth?
You can think at the job of the compiler like this; it reads the source file token by token (not exactly line by line) and when sufficient tokens are read, it outputs the translation. It repeats that, until the source file is (correctly) finished: the job of the compiler is done.
For every token the compiler reads, it needs to know what the token represents. If it doesn't know, an error is generated.
So, while compiling your function
void function()
{
x += 3
}
it encounters an "x" but does not know what it represents (an integer? A float? Something else?). -error-.
Why do we need to declare global variables before function defining and declaring
Declaration and Definition are two different things. The compiler needs a declaration in order to know how to manage an identifier; the real definition can be somewhere else, even in another source (or already compiled) file.
And one more question. I know that we can define function after main function provided we declared this function before main. Then how does main function see these functions after main function? Does the compiler first read the whole file and then run main() or sth?
As explained before, all the compiler needs is a declaration, so it can output correct (object) code. If you declare function(), then define main(), then define function(), the compiler has enough to generate correct output, which will consist of code for main() and code for function() (we can say "in this order"). The next step, the linker, will take care to connect these two functions.
The definition of function() could also be absent: the compiler still would generate correct code for main(); the linker would instead complain, unless you tell it where to find the definition/implementation of function().
Also note that a definition is also a declaration. So if in your source you declare function() and then main(), you don't need forward declaration.
In the comments I've read that perhaps you are confusing interpreters with compilers - this is true, if you try to compare Python with C: very different beasts. A big difference is compiler vs interpreter, the compiler generates data (object code) but does not link it (and neither runs it). An interpreter instead is a compiler+linker+runtime, all packed together. Normally a compiler generates code that is much faster than the equivalent interpreted program, but to do this it needs accurate informations (precise types and declarations) and often (always?) is less versatile. The interpreter is often more versatile but it can not exploit all the optimizazions a good compiler can do.
Why do we need to declare global variables before function defining
and declaring since we call this variablefunction after this
declaration?
The c language is a strictly typed language. When the compiler processes an identifier it needs to determine its type to generate correct object code.
It is not necessary that a global variable used in a function shall be declared exactly before the function definition. But in any case it shall be declared before its usage in a function.
Here is a demonstrative program.
#include <stdio.h>
void function( void )
{
extern int x;
x += 3;
}
int x = 3;
int main( void )
{
function();
printf( "x = %d\n", x );
}
The program output is
x = 6
Here the variable x declared within the function refers to the global variable x defined after the function.
Then how does main function see these functions after main function?
Does the compiler first read the whole file and then run main() or
sth?
C is a compilation language. It does not run programs. It generates object code that then after some processing by the linker can be run.
In the point where a function is used what the compiler is need is the type of the function that to check whether the function is used correctly. If the function is an inline function then it can substitute its call for the function body It can rebuild the object code when the inline definition in the translation unit will be known.

A function's prototype is similar to declaring the function in the calling routine?

If there is no function prototype, a function is implicitly declared by its first appearance in an expression.
In C, if a function return anything else than int it is a good habit to declare the function inside the caller function like 1st example of code.
But you are always constrained by the compiler to write the prototype, the reason is that he does not know who the function is because it is declared underneath the main() function.
The question is: These two are equivalent? Will either writing the prototype or declaring explicitly the function inside the main() return the wanted result? How can it return a bad value if you are constrained always to use one of this two ways?
if the function is declared in the same script as the caller function is (here main())
prototype
declare explicitly function in main().
if the function is declared in another file
prototype
declare explicitly function in main()
E.g:
int main()
{
double doSomething(int a);
printf("%d", doSomething(2) );
}
double doSomething(int a)
{
return a * 2.0;
}
vs
double doSomething(int a);
int main()
{
printf("%d", doSomething(2) );
}
double doSomething(int a)
{
return a * 2.0;
}
This thread is almost what i needed but it did not answer all my questions.
C language - calling functions without function prototype
These two declarations are equivalent until in the first case the function doSomething will be required in some other function except main.
In this code snippet
int main()
{
double doSomething(int a);
//..
there is a function prototype of the function doSomething.
From the C Standard
A function prototype is a declaration of a function that declares the
types of its parameters
That is before the function definition that is also its declaration the name of the function will be visible only in the block scope of main.
Consider the following program
#include <stdio.h>
void g( void )
{
f( 20 );
}
int main(void)
{
void f( int );
f( 10 );
return 0;
}
void f( int x )
{
printf( "x = %d\n", x );
}
The compiler will issue an error for this statement
f( 20 );
because the name f is not yet declared.
But this statement
f( 10 );
is correct because the name inside the block scope of main is already declared.
To make it more clear take into account that functions always has a linkage opposite to variables declared in a block scope without a storage class specifier.
So this declaration in main
double doSomething(int a);
is equivalent to the declaration
extern double doSomething(int a);
And the linker will find the function definition even if the function initially is declared in a block scope.
In modern C, you should always declare a function before using it. (That includes defining a function before using it, because a definition is a declaration.) Implicit declaration of functions to return int is a behavior of very old verions of C. It should not be used, compilers should at least warn about it, and you should set your compiler to make it an error, not a warning.
Functions are usually declared outside of other functions. There is nothing explicitly wrong about declaring a function inside another function, but we rarely do it because we generally want functions to be visible throughout a translation unit, not just in one specific place. (A translation unit is one source file together with all the files it includes via #include directives.) The names of functions obey the same scope rules as object names: If it appears outside of any function, it has file scope. If it appears inside a block (a list of statements inside braces, { … }, which includes function bodies), it has block scope and is only visible in that block.
Whether a function is declared at file scope or block scope will not affect how it behaves.
main is not special in this regard. You are likely asking about main because you are early in your programming education, and you mostly call functions just from main. However, functions may be called from other functions, and the rules about scope and name visibility are not particular to main. If a function is declared at file scope, its name is visible throughout the rest of the translation unit. If a function is declared at block scope, whether inside main or another function, its name is visible throughout the rest of that block.
If a function is defined to return double but you use it without declaring it, and your compiler allows that, then you can expect your program to work incorrectly. The compiler will not automatically convert double to int. The function type is important to tell the compiler what the function returns because the compiler expects certain bits to be in certain places when the function returns, and it writes instructions relying on that.

What are "prototypes" in a C program?

The book's I'm using to learn C explains something called "prototypes" which I couldn't understand properly. In the book, the following sample code explains these "prototypes". What does this mean here? What are the "prototypes"?
//* two_func.c -- a program using two functions in one file */
#include <stdio.h>
void butler(void);
int main(void)
{
printf("I will summon the butler function.\n");
butler();
printf("Yes! bring me some tea and writable DVD's.\n");
getchar();
return 0;
}
void butler(void) /*start of function definition*/
{
printf("You rang,sir.\n");
}
Please explain in simple terms.
Function prototypes (also called "forward declarations") declare functions without providing the "body" right away. You write prototypes in addition to the functions themselves in order to tell the compiler about the function that you define elsewhere:
Your prototype void butler(void); does all of the following things:
It tells the compiler that function butler exists,
It tells that butler takes no parameters, and
It tells that butler does not return anything.
Prototypes are useful because they help you hide implementation details of the function. You put your prototypes in a header file of your library, and place the implementation in a C file. This lets the code that depends on your library to be compiled separately from your code - a very important thing.
In this context prototype is a more generic term for what in C would be called a function declaration, i.e.:
void butler(void);
You may also find it called function signature. Both terms actually refer more to how butler() is defined from a conceptual point of view, as a function that doesn't take any argument and doesn't return a value, rather that to the fact that its declaration is enough for you to use it in your source code.
This is the prototype:
void butler(void);
Basically it defines butler as a function that takes no parameters and has no return value. It allows the compiler to continue onwards, even though the butler function has not yet really been defined. Note that the prototype doesn't contain any actual code. It simply defines what the butler function looks like from the outside. The actual code can come later in the file.
If your code had been
#include <stdio.h>
int main(void) {
butler(); // note this line
}
void butler() { return; }
The compiler would have stopped at the note this line section, complaining that butler() doesn't exist. It will not scan the whole file first for functions, it'll simply stop at the first undefined function call it encounters.
Prototype comprises the return type of a function, its name and the order of different types of parameters that you pass it.
If you write the function definition before calling the function, then a prototype is not necessary. But, as is the case in your example, the function butler() is called BEFORE its definition and so, a prototype is necessary to tell the compiler that such a function exists which will have so and so return type and parameters.
Otherwise, writing the function definition after calling the function will result in error.
void butler(void);
Is Called prototype or declaration of function.
And below is the function definition.
void butler(void) /*function definition */
{
printf("You rang,sir.\n");
}

C error: prototype function declaration not in scope

I don't understand what my error is:
void main(char string[])
{
strcpy(command_E,string);
processCMD(); /*FIRST ERROR: prototype function declaration not in scope */
}
void processCMD(void) /*SECOND ERROR: external item attribute mismatch */
{
.... /*rest of code not displayed*/
At the point where you use processCMD(), you haven't declared a prototype for it, so it gets a default one.
The fact that you haven't declared it causes the first error.
The fact that your actual definition conflicts with the default one created because you hadn't declared it is the cause of your second error.
The solution is to either define the function before use:
void processCMD(void) {
blah blah blah
}
void main (char string[]) { // not really a good definition for main, by the way.
strcpy(command_E,string);
processCMD();
}
or provide a prototype before use:
void processCMD(void);
void main (char string[]) { // not really a good definition for main, by the way.
strcpy(command_E,string);
processCMD();
}
void processCMD(void) {
blah blah blah
}
As to the declaration of main, the two canonical forms are:
int main (void);
int main (int argc, char *argv[]); // or char **argv.
Others are allowed by the standard (implementation defined) but those two are required (at least for hosted implementations - freestanding implementations like embedded systems or operating systems can pretty well do whatever they want).
You need a prototype before the the first use of the function to declare it so the compiler knows what kind of arguments the function takes (if any) and what it returns:
void processCMD(void); // prototype
void main(char string[])
{
strcpy(command_E,string);
processCMD();
}
void processCMD(void)
{
.... /*rest of code not displayes*/
Alternatively, you could defined the function before it's first use (since the definition will provide the information the compiler wants.
Typically, the prototype will go in a header file so other modules can use the function since function definitions can only be in one source file (barring such things as making the function static, which makes each instance of the function 'private' to a module, or marking the function as inline, which enables multiple definitions).
Some additional prototype trivia:
Generally in C, the lack of a protoype is not an error in itself - if the compiler sees a function call without having seen a prototype it will assume that you're passing the right parameters, it will apply 'default promotions' to paramters (basically convert things to int ot double as appropriate), and will assume the function returns an int. If those assumptions are wrong, then the program is incorrect and will have undefined behavior. Compilers can often be configured to emit warnings or errors for calling functions that don't have prototypes (apparently yours has). In C++, calling a function without a previous protoype being seen (or the full function definition) is always an error.
In C, there's a difference between:
void processCMD();
and
void processCMD(void);
The first is a function declaration, but not a prototype - it tells the compiler that processCMD is a function and that it returns void instead of int. But it doesn't tell the compiler anything about the arguments. The compiler will still allow function calls to be made with arguments passed and will apply the default promotions. (Again, this feature might be disabled by compiler configuration).
The second is a prototype that specifically tells the compiler that the function takes no arguments.
In C++, both are equivalent and specifically tell the compiler that the function takes no arguments.

How to implement a "private/restricted" function in C?

I was asked a very interesting question during a C interview: How can you implement a function f() in such a way that it can only be called from a particular g() function. If a function other than g() tries to call f() it would result in a compiler error.
At first, I though this could be done with function pointers and I could get close to blocking the call at runtime. But I was not able to think of a compile time strategy. I don't even know if this is possible using ansi C.
Does anyone have any idea?
Here's one way:
int f_real_name(void)
{
...
}
#define f f_real_name
int g(void)
{
// call f()
}
#undef f
// calling f() now won't work
Another way, if you can guarantee that f() and g() are the only functions in the file, is to declare f() as static.
EDIT: Another macro trick to cause compiler errors:
static int f(void) // static works for other files
{
...
}
int g(void)
{
// call f()
}
#define f call function
// f() certainly produces compiler errors here
Put g() and f() in the same module, and declare f() as static. The static keyword makes f() available only to functions in the same module, or source file.
You might also want to mention that no other methods should be allowed in the module with f() and g(), otherwise they could call f().
PS - I really think Chris Lutz' answer is actually the best. It mentions this approach, but also a clever macro renaming that works with fewer environmental conditions (does not require the module file specifically for these two functions).
Note also that with a macro, you could do the following:
#define f() f_should_not_be_called_by_anything_except_g
Which would present a nice error message, and auto-completers (like Visual Studio) would show that tip when the user types f().
You can make module-private functions with the static keyword:
static void func(void)
{
// ...
}
Then, func() can only be called by other functions defined in the same file (technically, the same translation unit: other functions whose definitions are included by a #include directive can still access it). func is said to have internal linkage. All other functions (that is, without the static keyword) are said to have external linkage.
Beyond that, no, there is no way to make functions inaccessible. You can use macros to change the name of the function, but other code can always still access it with the appropriate name.
Place f() and g() in the same source file, declare f() static.
An option for GCC is to use nested functions. While it's not standard C, it works quite well.
It is only possible coincidentally.
If functions f() and g() are both in the same source file, and there are no other functions in the file, and if g() never returns the function pointer to f() to any of its callers, then making f() static will do the job.
If other functions must appear in the same source file, placing f() at the bottom of the file as a static function, and only defining g() immediately after it would achieve more or less the same effect - though if you didn't tell the compiler to generate errors on 'missing declarations' other functions could call it with warnings.
#include <stdio.h>
extern void g(void); /* in a header */
/* Other functions that may not call f() go here */
static void f(void)
{
puts("X");
}
void g(void)
{
f();
}
Clearly, this technique cannot be extended reliably to another pair of functions in the same file - x() and y() - such that x() and only x() can call y() while g() and only g() can call f() at the same time.
However, normally you would rely on the programmers' discipline and simply make f() static in the source file, along with a comment that only g() may call it, and then discipline anyone who modifies the code so that a function other than g() calls f().
You could implement f() as a macro and let the pre-compiler handle it:
#include <stdio.h>
#define f(s) printf("Hello %s!\n", s);
void g(char * w) {
f(w);
}
#undef f
int main(void) {
/* f() calls will produce an undefined reference to 'f' linker error */
g("World");
return(0);
}
In this way, there is no other exposed function and no need for a static function.

Resources