I know that there are multiple ways to accomplish this, i.e static could be used on both the declaration and the definition OR it could only be used on the declaration.
Is this the common way of doing so?
// `static` on both the declaration and definition.
static void f1();
static void f1(){}
// `extern` on only the declaration (shared header file).
// then define in a single source file.
extern void f2();
void f2(){}
// `inline` usually doesn't need a declaration, just define it in a shared header file.
inline int f3(){}
int main(){
return 0;
}
Related
Lets say I have the following struct:
typedef struct
{
uint8_t *ptr;
} Example;
If I have in file1.c:
// Global variable
uint8_t myVar;
How can I initialize an Example with the ptr member pointing to myVar, in file2.c?
I know I could just do:
extern uint8_t myVar;
// Global variable
Example myExample = {.ptr = &myVar};
But myVar would be visible in all the scope of file2.c and I'm trying to avoid that.
A pointer or other object can be made available within a source file without making symbols used in its initializers be visible by declaring it extern in one source file (or more) and defining it in a separate source file.
Create a separate C file, such as myExample.c, containing a definition of myExample:
#include "myExample.h"
extern uint8_t myVar;
Example myExample = { .ptr = &myVar };
Create a header file, such as myExample.h, that declares myExample:
typedef struct
{
uint8_t *ptr;
} Example;
extern Example myExample;
Then include the header file in any source file where you want to use myExample. That source file will see myExample but not myVar.
Also compile the new C file and link it in with your program.
you need to add the function in the file.c
static uint8_t myVar;
uint_8 *getMyVat(void)
{
return &myvar;
}
in file2.c
void foo(void)
{
Example myExample = {.ptr = getMyVar()};
}
But it cannot be used as an initialisation of the static storage variables
I am afraid you cannot. C language has only 3 scopes:
global scope is (potentially) visible to the whole program (across different compilation units)
static scope is visible to a compilation unit
local scope is visible to the block where the variable is declared
If you want to initialize a global or static variable, its initializers can only contain global or static symbols, which have to be visible throughout all the source file.
in my university our teacher taught us "we define function prototype before main function. Like:
#include<stdio.h>
void findmax(float, float);
int main()
{
//code goes here
}
But today my friend showed me they learned they put prototype inside main function. Like:
#include<stdio.h>
int main()
{
void findmax(float, float);
float firstnum, secondnum;
printf("Enter first:");
scanf("%f", &firstnum);
printf("Enter second:");
scanf("%f", &secondnum);
findmax(firstnum, secondnum);
}
void findmax(float x, float y)
{
float maxnum;
if(x>y)
{
maxnum=x;
}
else
{
maxnum=y;
}
printf("The max is %f", maxnum);
}
They both works.I wonder if there are differences between them. Thanks.
Can we define function prototype in main function in C?
Yes.
I wonder if there are differences between them
The difference is that in first snippet prototype is global while in second it is local to main. findmax will be visible after its declaration and/or definition.
#include<stdio.h>
void foo();
int main()
{
void findmax(float, float);
foo();
findmax(10, 20); // It knows findmax by the prototype declared above
}
void findmax(float x, float y)
{
float maxnum;
if(x>y)
maxnum=x;
else
maxnum=y;
printf("The max is %f", maxnum);
}
void foo(){ // foo is using findmax after its definition.
findmax(12, 30);
}
If foo is declared in outside a function, it can be called from any function in the same file:
void foo(); // <-- global declaration
int main() {
foo(); // <-- works, foo() is declared globally
}
void otherfunc() {
foo(); // <-- works, foo() is declared globally
}
However, if foo is declared inside a function, it can only be used within the same scope:
int main() {
void foo(); // <-- scoped declaration
foo(); // works, foo() is declared in same scope
}
void otherfunc() {
foo(); // ERROR: foo() is not declared in scope of otherfunc()
}
In either case, foo must be declared before it is used.
If you declare the function in main() it is scoped in the main() and you cannot access it in another function. But if you declare it at the start of the file or in a header file you can use it in any function.
A straightforward answer to your question would simply be a YES. But when it comes to the scope, I'd like to add more.
What others suggest is right -- if you declare a function inside another function, the first one's scope is usually limited to the second one. For the example you provided, it is perfectly safe to say so. But that may not be the case always. Consider the following code:
#include <stdio.h>
/* Can be accessed from anywhere in this file
* because defined before anything else.
*/
void print_hello() {
puts("Hello!");
}
int main() {
void print_hello(); /* Not needed actually */
void print_namaste();
void print_hi();
print_namaste();
print_hi();
}
/* The following two functions cannot be
* accessed from within the above two functions
* unless these two are declared inside them
* or at the starting of this file
*/
void print_namaste() {
puts("Namaste!");
print_hello();
}
void print_hi() {
puts("Hi!");
}
Here you can see that print_hello() is declared inside main(). But that is redundant. print_hello() has already been introduced into the compiler. There is no need of declaration to use it inside this file (if you use it inside other files and compile them independently, then you'll have to declare it inside those files or write a header file to do so). What my point is, declaring print_hello() inside main() has not rendered it local, at least in this example. You can see print_namaste() calling it successfully without any additional declaration.
But that is not the case with print_namaste() and print_hi(). They require declaration to be used from within main() because they are introduced to the compiler only after main() has been defined.
print_namaste() will only be visible to the functions inside which we declare it, and to those functions which are defined after print_namaste(). In this example, print_namaste() is not visible to print_hello() (unless declared inside it or before it), but visible to main() because declared inside it, and visible to print_hi because its definition comes only after the definition of print_namaste().
In VC2008 the following is valid:
int main(void)
{
void foo(void);
//...
}
void test(void)
{
foo();
}
My believe was that prototype declarations are valid anywhere and their scope is at least from the point of declaration to the end of file.
Looking at the C99 standard:
6.2.1 Scope of Identifiers
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... For each different entity that an identifier designates, the identifier is visible (i.e., can be
used) only within a region of program text called its scope... identifier has scope determined by the placement of its declaration (in a
declarator or type specifier). If the declarator or type specifier that declares the identifier
appears outside of any block or list of parameters, the identifier has file scope, which
terminates at the end of the translation unit. If the declarator or type specifier that
declares the identifier appears inside a block or within the list of parameter declarations in
a function definition, the identifier has block scope, which terminates at the end of the
associated block.
This would mean that VC2008 is wrong.
I have the following piece of code where I define a couple of external (global) variables after the place in code where I need to use them.
In order to do so I use the keyword extern to declare them without reserving storage for them.
int main(int argc,char *argv[])
{
extern int a;
extern double b;
/* ...use the variables somehow... */
{
int a = 10;
static double b = 2.0;
if I do so, the compiler complains that I'm defining the b variable to be static (thus with internal linkage),when before I declared it to be extern.
But if I invert the order and define it before using it and declare it inside main ( which is otpional I know...) everithing is fine.
static double b = 2.0;
int main(int argc,char *argv[])
{
extern int a;
extern double b;
/* ...use the variables somehow... */
{
int a = 10;
so what if I'd like to use an external private variable (i.e. with internal linkage) before I define it? is it forbidden and why?
The extern keyword tells the compiler that the variable we refer to is located in a different translation unit (another source file basically), while the static keyword means that the variable (in the case of global variables) is local to the current translation unit and cannot be seen in other source files, so it makes no sense to use the two keywords together.
Once you have declared b as global in the same file, it is visible in main and there is no need to declare it again, you just can use it.
If on the other hand it is declared in a different translation unit as a global variable, the extern keyword becomes necessary.
For C99, is the following syntax legal when splitting up static inline functions into separate declarations and definitions?
foo.h:
#include "foo_decl.h"
#include "foo_def.h"
foo_decl.h:
#ifndef _FOO_DECL_H
#define _FOO_DECL_H
/* Here we document foo */
inline int foo(int x);
/* Here we document bar */
inline int bar(int x, int y);
#endif // _FOO_DECL_H
foo_def.h:
#ifndef _FOO_DEF_H
#define _FOO_DEF_H
inline static int foo(int x) { return x+3; }
inline static int bar(int x, int y) { return x-y+22; }
#endif // _FOO_DEF_H
The declaration is really useless to the compiler, but it serves a purpose for collecting documentation for functions in one place without getting cluttered by interspersed implementation details.
Or should foo_decl.h include the static keyword?
This is undefined behaviour according to 6.2.2/7:
If, within a translation unit, the same identifier appears with both internal and external linkage, the behavior is undefined.
The line inline int foo(int x); declares foo to have external linkage (6.2.2/5), but static int foo(int x) { declares foo to have internal linkage.
If you really want to do this then the versions in foo_decl.h and foo_def.h must either both have static, or neither have static. In the latter case exactly one .c file must have extern inline int foo(int x);.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I share variables between different .c files?
If I have two source files, and one header: file1.c, file2.c, and header.h, and:
--header.h--
int i;
--file1.c--
#include <header.h>
i = 10;
int main() {
func();
return 0;
}
--file2.c--
#include <header.h>
void func() {
printf("i = %d\n", i);
return;
}
I get the warning that i defaults to an int. What could I do if I want to have i as a float for instance?
Make it
extern int i;
in the header and
int i = 10;
in file1.c.
The warning means that for the (incomplete) declaration i = 10; in file1.c, the "implicit int" rule is applied, in particular, that line is interpreted as a declaration (since an assignment cannot appear outside function scope).
You have a couple of errors in your code. The first is that you define the variable i in the header file, which means that it will be defined in all source files that include the header. Instead you should declare the variable as extern:
extern int i;
The other problem is that you can't just assign to variables in the global scope in file1.c. Instead it's there that you should define the variable:
int i = 10;
Declare it as extern in the header (this means memory for it is reserved somewhere else):
/* header.h */
extern int i;
Then define it in only one .c file, i.e. actually reserve memory for it:
/* file1.c */
int i = <initial value>;
In the header use
extern int i;
in either file1.c or file2.c have
int i = 20;
If you want float just change int to float
In 99.9% of all cases it is bad program design to share non-constant, global variables between files. There are very few cases when you actually need to do this: they are so rare that I cannot come up with any valid cases. Declarations of hardware registers perhaps.
In most of the cases, you should either use (possibly inlined) setter/getter functions ("public"), static variables at file scope ("private"), or incomplete type implementations ("private") instead.
In those few rare cases when you need to share a variable between files, do like this:
// file.h
extern int my_var;
// file.c
#include "file.h"
int my_var = something;
// main.c
#include "file.h"
use(my_var);
Never put any form of variable definition in a h-file.