extern storage classes in c

Go To Last Post
22 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have been reading extern storage classes but I do not understand.  I wrote a program that has two files 

 

File 1 

#include <stdio.h> 
int x = 0;   
void foo();

int main() {
  foo(); 
  printf("%d", x);
 
  return 0;
}

 

File 2

extern int x;
void foo() { 
  x++;
}

 

Can anyone explain how the external variable is used in c language?

This topic has a solution.
Last Edited: Mon. Feb 10, 2020 - 04:18 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

Extern basically tells the compiler the variable or function is defined in another file. Your example of usage is correct.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

sky33 wrote:
I do not understand

What don't you understand about it?

 

As  Kartman says, what you show is correct - as far as it goes.

 

It's hard to explain when we don't know what needs explaining!

 

One thing that's missing is to use a so-called "Header" file for the extern declaration, but that's an extra nicety - the code as shown is perfectly valid.

 

See: https://www.avrfreaks.net/commen...

 

This is standard 'C' stuff - so should be covered in standard C textbooks, tutorials, references, etc ...

 

sky33 wrote:
Can anyone explain how the external variable is used in c language?

 

http://c-faq.com/decl/decldef.html

 

Here are some 'C' learning & reference materials for you - including a free online 'C' textbook:

 

http://blog.antronics.co.uk/2011...

 

 

EDIT

 

sky33 wrote:
I have been reading

It may also be helpful to say what you've been reading - if it's on the interwebs, give a link so that we can see it in context.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Mon. Feb 10, 2020 - 10:53 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
This is standard 'C' stuff

And it's not just 'C'

 

Any programming language which supports modular programming has to have some means for a "module" to export things  - so that they are available for other modules to use - and a means for a module to import things from elsewhere.

 

In some other languages, you have to explicitly "export" things; or specify them as "public".

 

In 'C', everything at file-scope (unless specified 'static')  is implicitly Public; ie, can be "seen" by other modules - so 'C' has no keyword to identify stuff as Public.

 

EDIT

 

More on the use of 'static' here:  https://www.avrfreaks.net/forum/what-happening-code-if-i-am-using-static-keyword-front-function-code

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Mon. Feb 17, 2020 - 08:43 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
What don't you understand about it?

As  Kartman says, what you show is correct - as far as it goes.

!

 

I was not sure what i am doing is right, I thought I should show my work so Anyone can tell if there is a mistake in this

 

 

awneil wrote:
One thing that's missing is to use a so-called "Header" file for the extern declaration, but that's an extra nicety - the code as shown is perfectly valid.

I have modified my code 

#include<stdio.h>
#include"other.h"

void Func();

int main() {

 int x = 0;
  Func();
  printf("%d", x);

  return 0;

}

 

I have other.h file , What should i put in this file ?


extern int x;
void Func() {  
  x++;
 
}

 

error: ld returned 1 exit status

 

Last Edited: Mon. Feb 10, 2020 - 12:33 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sky33 wrote:
What should i put in this file ?

Did you read the 'C' FAQ link I posted previously ?

 

http://c-faq.com/decl/decldef.html - it answers exactly this question!

 

And the forum link ...

 

https://www.avrfreaks.net/commen...

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Mon. Feb 10, 2020 - 12:24 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
Did you read the 'C' FAQ link I posted previously ?

I have read these links, as well as read other links. What is wrong with my header file, because of which I am not getting the correct output

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sky33 wrote:
I have read these links

So have you done what they tell you?

 

sky33 wrote:
What is wrong with my header file

You haven't shown your header file - so it's impossible to tell!

 

 because of which I am not getting the correct output

As always, you need to:

  1. show your complete program- all the source files
  2. tell what you expected to happen
  3. tell what is actually happening
  4. tell what investigation / testing / debugging you have done to find the issue(s)

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Mon. Feb 10, 2020 - 12:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please do not edit you post after someone has replied to it!

 

It makes nonsense of the replies, and makes the thread impossible to follow.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sky33 wrote:

I have other.h file , What should i put in this file ?

extern int x;
void Func() {
  x++;

}

If that is what's in your header, then you have not followed what the links told you.

 

There you have put the definition of the function in the header - do not do that!

 

sky33 wrote:
error: ld returned 1 exit status

That just tells you that the linker returned some error - there will be more detail of what, exactly, the error(s) was/were earlier in the build output ...

 

EDIT

 

See: https://www.avrfreaks.net/commen...

 

EDIT 2

 

Also: https://www.avrfreaks.net/commen...

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Mon. Feb 10, 2020 - 01:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

Please do not edit you post after someone has replied to it!

 

It makes nonsense of the replies, and makes the thread impossible to follow.

 

When I was editing post you replied,  that's reason I haven't seen your reply 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Read, and follow, this...

 

 

Attachment(s): 

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sky33 wrote:
When I was editing post you replied,  that's reason I haven't seen your reply 

Hmmm ... it looks suspicously like you revised the post in the light of my replies ...

 

Anyhow, the thing to do is to never make significant changes after posting.

 

If you want to make updates, then be sure to keep the original intact, and make the updates clear - eg, as I did in #10.

 

Anyhow, back to the point:

 

in #10, I wrote:
If that is what's in your header, then you have not followed what the links told you.

 

There you have put the definition of the function in the header - do not do that!

 

So you need to go back to those links; in particular, be sure to understand the difference between a definition and a declaration - as that is the key here!

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Brian Fairchild wrote:
Read, and follow, this...

Which is a bringing-together of this:  https://www.avrfreaks.net/forum/tut-modularizing-c-code-managing-large-projects

 

But note that Dean is a bit fuzzy on the distinction between declarations & definitions ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I compiled your files and display using "avr-nm".  See below.

Note how in one object file 'x' is "B" or (bss) for zero-initialized data.  In the other object file 'x' is "U" for uninitialized. 

The compiler makes the "U" designation based on your use of "extern" in the declaration.

The linker will resolve the defined 'x' in f1.o with the undefined 'x in f2.o.

mwette$ avr-nm f1.o
0000003e a __SP_H__
0000003d a __SP_L__
0000003f a __SREG__
         U __do_clear_bss
         U __do_copy_data
00000000 a __tmp_reg__
00000001 a __zero_reg__
         U foo
00000000 T main
         U printf
00000000 B x
mwette$ avr-nm f2.o
0000003e a __SP_H__
0000003d a __SP_L__
0000003f a __SREG__
00000000 a __tmp_reg__
00000001 a __zero_reg__
00000000 T foo
         U x

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

awneil wrote:
But note that Dean is a bit fuzzy on the distinction between declarations & definitions ...
The way I always remember this is that there is something IN a defINition but not a declaration. So declaration is where you just say to the compiler "there's going to be one of these created at some point but just for now all you really need to know about it to be able to handle it is either the data type (variable) or the input and output parameter types (functions)". The defINition is where you actually create the object.

 

With a special exception of "static inline" functions a .h file should never contain anything but declarations. You can tell a variable is a declaration not a definition because it always has "extern" on the front. While you can (optionally) do that for functions too you can usually tell a function declaration from a definition because one ends in a semicolon (eg "int add(int, int);") while the definition ends in a set of braces with (usually) some code in the middle.

Last Edited: Mon. Feb 10, 2020 - 01:50 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
The way I always remember this is that there is something IN a defINition but not a declaration

I like that - I shall have to remember it!

 

smiley

 

The defINition is where you actually reate (sic) the object.

* "create"

 

Indeed: the defINition is the thing which actually causes resources to be consumed; ie, memory (whether data or code) assigned.

 

 

you can usually tell a function declaration from a definition because one ends in a semicolon

Isn't it always the case that you tell a function declaration (aka "prototype")  because it ends in a semicolon?

 

EDIT

 

clawson fixed the typo while I was typing!

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Mon. Feb 10, 2020 - 01:55 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

If you want a minimalist example try this.

 

Create 3 files:

 

// my_module.c
// Source code file for your module
// Have it create a function & a variable to be used by other modules

 

// my_module.h
// Header file for your module
// This allows other modules to access your function & variable

 

// main.c
// This will contain you main() function
// Have your main() function access the variable & function exported by the other module

 

Now fill-in those files ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

sky33 wrote:
I wrote a program that has two files 
BTW your mistake was to stop at TWO. Usually when things are shared from one module to another there are THREE files involved. A .c file that has the definition(s) of what is being shared, a .h file that publicizes / documents what the thing(s) is/are and another .c file that includes the .h and makes reference to the exposed item(s) to actually use them. So:

// shared.h - declarations...

extern int x;
void foo();
// foo.c - defINitions of "exposed" items

int x;
void foo() {
  x++;
}
// main.c - consumer/user of things provided by foo.c and documented in shared.h

#include <stdio.h>
#include "shared.h"

int main() {
  x = 37;
  printf("%d\n", x);
  foo();
  printf("%d\n", x);

  return 0;
}

Of course this is an UTTERLY TERRIBLE way to actually do this. No way should "x" be global and available for main() to "see" and change. It should belong privately to foo.c and the only access to it might be the foo() function to increment it and return the current value. If there is a need for main() to be able to set a starting value then make another function (bar() ?) that allows main() to ask for the value to be set.

 

There is little point in learning the mechanics of the C language if you don't understand how they are intended to be used.

 

"encapsulation": keeping data hidden from prying eyes so access to it can be controlled is a key concept in programming. Otherwise this code might have a "x = 123" anywhere across all the files that mysteriously changes the "x" that "belongs" to foo.

 

If you are just at the learning stage I would highly recommend you consider learning C++ not C as it is designed to make this kind of stuff "natural". What's more all that stuff in shared.h would all be grouped together in a "class" (like a struct) to more definitely show they are connected.

Last Edited: Mon. Feb 10, 2020 - 02:39 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

in #18, awneil wrote:
Now fill-in those files ...

 

Ha! clawson has done that for you - in #19 !

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks to all of you to provide detail description.  I now understand use of the external storage classes

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sky33 wrote:
I now understand use of the external storage classes

Jolly good - so please mark this as solved.

 

btw: Note that  'extern' is a storage class - not "classes".

 

This is not to be confused with Classes in C++ ...

 

EDIT

 

typos

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Mon. Feb 10, 2020 - 04:41 PM