Function declaration inside of function — why? - c

I am reading the book "Programming in C" and found in Chapter 10 an example like this:
#include <stdio.h>
void test (int  *int_pointer)
{
     *int_pointer = 100;
}
int main (void)
{
     void test (int  *int_pointer);
     int  i = 50, *p = &i;
     printf ("Before the call to test i = %i\n", i);
     test (p);
     printf ("After the call to test i = %i\n", i);
     return 0;
}
I understand the example, but I don't understand the line void test (int *int_pointer); inside of main. Why do I define the signature of test again? Is that idiomatic C?

It's definitely not idiomatic C, despite being fully valid (multiple declarations are okay, multiple definitions are not). It's unnecessary, so the code will still work perfectly without it.
If at all, perhaps the author meant to do
void test (int *int_pointer);
int main (void) {
...
}
in case the function definition was put after main ().

void test (int *int_pointer); is just a declaration (or prototype) of function test. No need of this declaration in main because you already have function definition before main.
If the definition of test were after main then it would be worth of putting its declaration there to let the compiler know about the return type, number of arguments and arguments types of test before calling it.

It's not idomatic C, but still valid.
The line is a declaration of the function test, not definition. A function can't be defined multiple times, but it's valid to have multiple declarations.

It is perfectly idiomatic C, and it actually has a (limited) practical use - although not one that is demonstrated by this example.
When you declare a function or other name at the usual global level, it is brought into scope for all function bodies in the code following the declaration. A declaration cannot be removed from a scope once it has been introduced. The function is permanently visible to the rest of the translation unit.
When you declare a function or other name within a braced block, the scope of the declaration is limited to that block. Declaring a function within the scope of another function will limit its visibility, and not pollute the global namespace or make it visible to any other functions defined in the same translation unit.
This is meaningless in the case of the example, because the definition of test also brings it into scope for all following bodies - but if test were defined in another translation unit, or even if it were defined only at the very bottom of this TU, hiding the declaration inside main would protect any other functions defined afterwards from being able to see its name in their scope.
In practical terms this is of limited use - normally if you don't want a function to be visible, you put it in another translation unit (and preferably make it static) - but you can probably contrive a situation where you might want to use this ability for constructing a module-loading system that doesn't export the original declarations of its components, or something like that (and the fact that this doesn't rely on static/separate object files might potentially have some relevance to embedded/non-hosted target environments where the linking step might not work as it does on PC, allowing you to achieve a measure of namespace protection in a purely-#include-based build system).
Example:
struct module {
void * (* alloc)(size_t);
void (* dealloc)(void *);
} loaded_module;
int main(void) {
if (USE_GC) { // dynamically choose the allocator system
void * private_malloc_gc(size_t);
void private_free_noop(void *);
loaded_module = (struct module){ private_malloc_gc, private_free_noop };
} else {
void * private_malloc(size_t);
void private_free(void *);
loaded_module = (struct module){ private_malloc, private_free };
}
do_stuff();
//...
}
// cannot accidentally bypass the module and manually use the wrong dealloc
void do_stuff(void) {
int * nums = module.alloc(sizeof(int) * 32)
//...
module.dealloc(nums);
}
#include "allocator_implementations.c"

It's not idiomatic; you typically see it in code that has problems getting their header files in order.
Any function is either used in one file only, or it is used in multiple files. If it is only used in its own file, it should be static. If it is used in multiple files, its declaration should be in a header file, and anyone using it should include the header file.
What you see here is very bad style (the function should either be static, or the declaration should be taken from a header style), and also quite pointless because the compiler can see the declaration already. Since the function is in the same file, it's not dangerous; if the declaration and function don't match the compiler will tell you. I have often seen this kind of thing when the function was in a different file; that is dangerous. If someone changes the function, the program is likely to crash or misbehave.

Related

C - void function(void), parameters and return values

I was given a large C-file containing several functions declared as follows:
void function_a(void);
The functions are written above the main program:
static void function_a(void) { .... }
Within the main program these functions are called as:
function_a();
Now as far as I know a function declared as written above does neither use parameters, nor have return values. However within these functions variables and arrays are used, which are not defined within these functions, but only in the main program.
Is this really correct C-Syntax? How can the functions access data from the main program, if it is not handed over as a parameter?
In addition the main program uses variables, which are calculated within the functions it calls.
Can you provide more context, please? In C you cannot access variables from another function but you can access global ones.
The following program is valid and will output 3, since i is a global variable and is visible everywhere.
#include <stdio.h>
int i = 2;
void plusone() {
i = i + 1;
}
int main() {
plusone();
printf("i = %d\n", i);
}
On the other side, the program below won't compile because i is local to main() function and is invisible elsewhere.
#include <stdio.h>
void plusone() {
i = i + 1;
}
int main() {
int i = 2;
plusone();
printf("i = %d\n", i);
}
Said that, usage of global variables is a bad practice and should be avoided.
So this:
//file_a.c
void function_a(void)
{
//...
}
Makes function_a a function that does not take any arguments and does not return any values. This function may be used by all other functions in the same file function_a was declared or in any other .c file that you tell the compiler to put together into the final program.
In other words, this function is accessible to all translation units of your program. If you have this function in a file called file_a.c, and you also have another file called file_z.c you can do this:
//file_z.c
void function_z(void)
{
function_a();
}
And all is fine.
On the other hand, this
//file_b.c
static void function_b(void)
{
//...
}
(and I renamed the function for clarity)
Makes function_b a function that does not take any arguments and does not return any values, just like function_a. However, it also says that function_b has static-file scope in the translation unit that begins or includesfile_b.c. That means it cannot be accessed by other translation units.
So if you now tried to do this in file_z.c:
void function_z(void)
{
function_b();
}
You would get compilation errors:
file_z.c:(.text+0xa): undefined reference to `function_b'
collect2: error: ld returned 1 exit status
Because each file_{a,b,z}.c is (or probably should be) the starting point of their own separate translation units, and function_b was declared with static-file scope in file_b.c, this function simply "does not exist" for other translation units.
Now, as to the variables declared just before function_b, I take they look somewhat like this:
//file_a.c
int array[10];
void function_a(void)
{
//...
}
That simply declares a global variable. It can be accessed by all functions in file_a.c, provided that they appear after the declaration. It can also be used by other translation units (like file_b.c or file_z.c) if you declare it like this:
//file_b.c
extern int array[10];
When you compile everything togheter, that declaration in the translation unit that starts with file_b.c will tell the compiler that array is not a file-scope variable within that file_b.c; rather the compiler will have to look for that variable in another translation unit, and then link them together so that all functions do the same thing to that block of 10 integers.
In C it is not at all possible to access local variables of another function or even scope.
Is the code compiling correctly? If yes these variables must be global defined either in the beginning or some header file.
If not make them global to access from non-parametric functions.

Apparently no meaning line in a program [duplicate]

I am reading the book "Programming in C" and found in Chapter 10 an example like this:
#include <stdio.h>
void test (int  *int_pointer)
{
     *int_pointer = 100;
}
int main (void)
{
     void test (int  *int_pointer);
     int  i = 50, *p = &i;
     printf ("Before the call to test i = %i\n", i);
     test (p);
     printf ("After the call to test i = %i\n", i);
     return 0;
}
I understand the example, but I don't understand the line void test (int *int_pointer); inside of main. Why do I define the signature of test again? Is that idiomatic C?
It's definitely not idiomatic C, despite being fully valid (multiple declarations are okay, multiple definitions are not). It's unnecessary, so the code will still work perfectly without it.
If at all, perhaps the author meant to do
void test (int *int_pointer);
int main (void) {
...
}
in case the function definition was put after main ().
void test (int *int_pointer); is just a declaration (or prototype) of function test. No need of this declaration in main because you already have function definition before main.
If the definition of test were after main then it would be worth of putting its declaration there to let the compiler know about the return type, number of arguments and arguments types of test before calling it.
It's not idomatic C, but still valid.
The line is a declaration of the function test, not definition. A function can't be defined multiple times, but it's valid to have multiple declarations.
It is perfectly idiomatic C, and it actually has a (limited) practical use - although not one that is demonstrated by this example.
When you declare a function or other name at the usual global level, it is brought into scope for all function bodies in the code following the declaration. A declaration cannot be removed from a scope once it has been introduced. The function is permanently visible to the rest of the translation unit.
When you declare a function or other name within a braced block, the scope of the declaration is limited to that block. Declaring a function within the scope of another function will limit its visibility, and not pollute the global namespace or make it visible to any other functions defined in the same translation unit.
This is meaningless in the case of the example, because the definition of test also brings it into scope for all following bodies - but if test were defined in another translation unit, or even if it were defined only at the very bottom of this TU, hiding the declaration inside main would protect any other functions defined afterwards from being able to see its name in their scope.
In practical terms this is of limited use - normally if you don't want a function to be visible, you put it in another translation unit (and preferably make it static) - but you can probably contrive a situation where you might want to use this ability for constructing a module-loading system that doesn't export the original declarations of its components, or something like that (and the fact that this doesn't rely on static/separate object files might potentially have some relevance to embedded/non-hosted target environments where the linking step might not work as it does on PC, allowing you to achieve a measure of namespace protection in a purely-#include-based build system).
Example:
struct module {
void * (* alloc)(size_t);
void (* dealloc)(void *);
} loaded_module;
int main(void) {
if (USE_GC) { // dynamically choose the allocator system
void * private_malloc_gc(size_t);
void private_free_noop(void *);
loaded_module = (struct module){ private_malloc_gc, private_free_noop };
} else {
void * private_malloc(size_t);
void private_free(void *);
loaded_module = (struct module){ private_malloc, private_free };
}
do_stuff();
//...
}
// cannot accidentally bypass the module and manually use the wrong dealloc
void do_stuff(void) {
int * nums = module.alloc(sizeof(int) * 32)
//...
module.dealloc(nums);
}
#include "allocator_implementations.c"
It's not idiomatic; you typically see it in code that has problems getting their header files in order.
Any function is either used in one file only, or it is used in multiple files. If it is only used in its own file, it should be static. If it is used in multiple files, its declaration should be in a header file, and anyone using it should include the header file.
What you see here is very bad style (the function should either be static, or the declaration should be taken from a header style), and also quite pointless because the compiler can see the declaration already. Since the function is in the same file, it's not dangerous; if the declaration and function don't match the compiler will tell you. I have often seen this kind of thing when the function was in a different file; that is dangerous. If someone changes the function, the program is likely to crash or misbehave.

Is a static variable name, same as function name allowed in C?

I was working on some C-output questions and found the following code:
http://ideone.com/O0tQnr
In this code , as one can see , inside main , a static variable having same name has been declared. For this I searched on Stack-Overflow and found
How are static variables with the same name in different functions identified by the System?
The answers given for this question suggest different approaches viz.
The names of static variables are usually included within the debugging symbol table.
some embedded ones (compilers) simply add a number to the end of each duplicate name
They are likely mangled in the table.
I wanted to know how are static variables actually implemented in C, as all answers are suggesting something different?
Also to check whether this was only a one-off chance I also ran the code:
http://ideone.com/zpRVCa
but the error:
prog.c:5:21: error: called object ‘GetSize’ is not a function or function pointer
int myvar=GetSize(GetSize);
^
prog.c:4:11: note: declared here
static GetSize;
^
indicates that the compiler found a conflicting declaration / redeclared Getsize.
Different entities may have the same identifier if they have different scopes or are in different name spaces1. In the case of int main() { static int main; … }, the first main has file scope, and the second main has block scope.
At any particular point, only one identifier is visible in a name space. In GetSize(GetSize), only the static GetSize is visible. It hides the int GetSize(int), so the function GetSize is not visible. Thus, this code gets an error.
An identifier declared at file scope with static has internal linkage. An object identifier declared at block scope without extern (including those that have static) has no linkage. Because these identifiers do not have external linkage, they never need to be known outside the current translation unit. Therefore, these identifiers do not need to appear in object files: There is no need for them to have names visible to the linker. They are typically accessed by code generated by the compiler during compilation of the translation unit, and this code addresses objects numerically (by location in memory), not by name.
Many C implementations provide debugging facilities. Debuggers generally need to know the names of things even if they have internal or no linkage. In these cases, the C implementation may use any scheme it desires to record information about names.
1 The name spaces of C are: label names; tags of structures, unions and enumerations; members of structures or unions (a separate space for each structure or union); and all other identifiers. The standard also refers to a name space for macro names.
The two cases you are describing have a fundamental difference. In the first case:
int main(){
static main;
int myvar=GetSize(main);
printf("%d",myvar);
return 0;
}
Here, you are inside the function main and declaring a static integer also called main. The function main is called from an external place which knows about main as a function and calls it as such. Inside the definition of main above, you have redefined main as the static integer, then calling GetSize(main) doesn't cause an error because it complies with the definition of GetSize.
In the second case:
int GetSize(int);
int main(){
static GetSize;
int myvar=GetSize(GetSize);
printf("%d",myvar);
return 0;
}
Here you've redefined GetSize to be a static integer, but then attempted to call GetSize as if it were a function. So you have a direct conflict in terms of the definition (static integer) and how you are using it (a function).
There's a clue in the error message: "not a function or function pointer". The compiler can't assume that the name to the left of the ( is a function name, because any expression yielding a function pointer is also allowed there, including a variable declared as a function pointer.
At the parsing stage, there's no type checking to help find the right variable. Here's a program that doesn't work for a similar reason:
int main(void)
{
struct { int x,y; } s = {0,0};
{
int s;
printf("%d\n", s.x);
}
}
The outer s is capable of fitting into the expression s.x, but the inner s is the one that is visible.
And here's a program that works because the outer-scoped function is not preferred over the inner-scoped variable, which happens to be a function pointer capable of being called with itself as an argument:
#include <stdio.h>
#include <stdlib.h>
void func()
{
puts("Everything's fine.");
}
void fp()
{
/* This won't happen. */
abort();
}
int main(void)
{
void (*fp)() = func;
fp(fp);
}

Putting variable declarations in a separate function in C

Is it possible to put the variable declarations in an external function? After reading from Wikipedia that:
an inline function is a function upon which the compiler has been requested to perform inline expansion. In other words, the programmer has requested that the compiler insert the complete body of the function in every place that the function is called, rather than generating code to call the function in the one place it is defined.
I hypothesized that the following might work. It did not take long for the compiler to slap my fingers :(
inline void declaration(){
int a;
}
int main(){
declaration();
a=2;
return 0;
}
This may not be how it is done but if you want a basic idea of how you can think about what happens when you inline a function.
Imagine the compiler turning your code into something like this, then you see why it will not work.
int main(){
{
int a;
}
a=2;
return 0;
}
The call to declaration() is replaced by the contents of the function including brackets, thus int a; is declared in an inner scope and is not visible in the main function.
No, this is not possible.
What is possible, is to use a preprocessor directive #define:
#define VARBLOCK int a, b, c; char ca, cb, cc;
int main()
{
VARBLOCK;
a = 2;
}
This would be a bad practice. Also these would still be variables only available in the scope of function where it were placed, without values being shared.
No - as far as I'm aware an inline function must behave semantically equivalent to a non-inline function; it doesn't affect what counts as legal code. It's just an optimization.
In particular, you could have a variable called a in both functions, but they'd be separate variables on the stack.
(Even if you could do this, I'd suggest it would be a very bad idea in terms of readability.)
inline functions are usually just a function containing no more than about 4 lines and you would want the compiler to do the optimization you where talking about since it would be faster to do what the function does, rather than adding extra code.
Inline expansion is used to eliminate the time overhead when a function is called. It is typically used for functions that execute frequently.
So there's nothing special with the inline function, rather than it might be handled differently by the compiler. They don't share their stack with any other function, which would be the only way for main to use a variable that is created in a different scope.
So my tip is; write your functions, and treat them as you usally should. Then when you are done, inline the short ones that you use a lot.
And if you really wanna create a variable in another function, allocate it on the heap in the function and return a pointer that you save and then set to 2 (your case). :) Just remember to free the memory!
You can do this, though:
#include <stdio.h>
int* GetMyIntAddress(void)
{
static int blah = 0;
return &blah;
}
int main(void)
{
printf("%d\n", *GetMyIntAddress());
*GetMyIntAddress() = 123;
printf("%d\n", *GetMyIntAddress());
return 0;
}
blah will be a global variable defined in the scope of the GetMyIntAddress() function.
If you add inline to the definition of GetMyIntAddress(), you are risking to get multiple independent instances of blah if the inline function is used in different modules (e.g. included from a shared header file).

Does the order of C objects matter?

Does the order in which C objects appear on the file matter?
For example, in functions, if I create two functions and the one above references the other one will it work? (Yes it will, I've tried it.)
Is the same in effect for static functions, INLINE functions, etc.?
Is the same in effect for structs? What happens if I reference a struct which is defined further down on the .c file?
Is this to any extend compiler-specific? How does the compiler work in this case? Does it first scan the whole file for all declarations/definitions and then attempts to dereference functions/symbols?
First, if by "if I create two functions and the one above references the other one will it work?" you mean something like this:
int foo()
{
return bar();
}
int bar()
{
return 0;
}
Then the compiler may do educated guesses at what bar() is, but it will at least spit a warning if bar() wasn't already declared. For symbols that can't be called (like variables or types), it's an outright error if they're used before they're declared.
In C, whenever you use an identifier (and no matter the kind of the identifier: it may be a function, a variable, a type, etc.), it should be declared beforehand. The various modifiers you may add to any identifier (like you said, static, inline and all the others) have no impact on this.
Do not confuse declaration and definition. A declaration is just telling the compiler that a name exists; a definition actually tells the compiler what it is.
For instance, this is a definition:
int bar() { return 4; }
Notice how it has a body, with (simple) code inside.
This is the matching declaration:
int bar();
The compiler will gladly accept the use of a function as soon as it sees either the declaration or the definition for it. For organization reasons and better flexibility, it's often better to write declarations for all your functions at the top of your C file (or inside an included header file) then the definitions.
So, my first example should look like this:
int foo();
int bar();
int foo()
{
return bar();
}
int bar()
{
return 0;
}
With the declarations above the C code, I can change the order of the functions in any way I like.
Typically something must be defined above where you use it. You can avoid this in different ways for different situations.
For functions, just provide a prototype above where it's called and all will be well.
int trol(int a, int b);
// use trol(int, int)
int trol(int a, int b) { }
If you have two functions, a and b, and they call each other and are defined in the order of: a, b, then you must provide b's prototype above the definition of a. a's prototype is not required because it is defined above where it is used inside b. Then the compiler will have no problems.
One other special case for functions is that you can use a function without declaring it and the compiler will try to infer the signature from the call. This answer explains it pretty well I think: Must declare function prototype in C?
For structs, you can use pointers to them before they are actually defined (but you can't access any of the fields) by providing a forward declaration:
struct s;
// use s*'s
struct s { };
(The above scenario facilitates recursive data structures like linked lists and trees; you can use pointers to structs before they are fully defined because the size of any type of pointer is constant.)
It matters, because if the compiler doesn't know what the function is - it will try to 'guess' (create a default int foo() prototype with matching parameters), and if your call is incorrect - you'll have mismatches (build errors, implicit castings, whatever).
It is common practice (if not even required) to declare the function before calling it (through prototypes aka forward declarations).
For functions with variable parameter lists (like printf) you must have a forward declaration for them to work properly. For example this code will not compile:
int foo(int a)
{
b(a);
b("hello", "kitty");
}
void b(int a, ...)
{
printf("%d", a);
}
But this - will:
#include <stdio.h>
int foo(int a)
{
return b(a);
}
int b(int a)
{
return printf("%d", a);
}
(with warning about the implicit forward declaration)
So in order to avoid dealing with the order of the objects in the file - use prototyping (forward declarations) to let the compiler know what's following.
From my experience, everything in C has to be written with the referenced "object" before the reference is made. I don't think this is specific to any compiler, but maybe there are some which I haven't found. Basically, everything always has to be:
Object Declaration
...
Object Reference

Resources