• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 241
  • Last Modified:

Extern in DevStudio 5.0

I have been trying to create a more convenient source code style by putting certain aspects of the program in totally separate c files. However, even if I declare them extern, they will not properly compile. I have several books and have use the help files but there is very little literature I have found on Extern. If anyone could help, I would appreciate it.
0
Keele
Asked:
Keele
  • 9
  • 6
  • 6
  • +7
1 Solution
 
kellyjjCommented:
what kind of errors/problems are you getting??  
0
 
Answers2000Commented:
You use extern for shared variables.

In your source, in only one .c file define the actual variable
e.g.
int x ;
int y = 0 ;
(outside the body of any functions)

In other .c files define the variable as extern before accessing it.
e.g.
extern int x ;
extern int y ;

If you find you are repeating the extern definitions in a lot then move the externs into a .h file and use #include to include these definitions into as many .c files as you want (this saves typing)

Is this enough to help or do you need more ?


0
 
duneramCommented:
I use an even easier method (a bit advanced)

The idea is to keep the hard work of knowing when/how to declare the variable(s) down to a minimum.  Ideally I will just want to include a .h file.  Here goes:

Say you have a .c file named  check.c

in the source I would put this (near the top):

#define CHECK_C_IMPLEMENTED_HERE
#include <check.h>
#undef CHECK_C_IMPLEMENTED_HERE

/* REST OF CODE GOES HERE */

------------------------------------------------------------------
oK In the .h file (check.h) I put this:

#ifndef CHECK_H_HDR
#define CHECK_H_HDR
/* prevents it from being included twice */

#ifndef CHECK_C_IMPLEMENTED_HERE
   /* when we fall into this piece, it means someone else is trying to use it */
extern "C"
#endif
short flag
#ifdef CHECK_C_IMPLEMENTED_HERE
              =  0  /* put your initialization code here */
                   
#endif
                    ; /* the ; always applies */
/* make sure you use the ';' above as it applies whether its an extern def or really being */
/* allocated here */


#endif  
 /* end of check.h */

If I want to use the variables in check.h from anywhere else, I simply only have to
#include <check.h>

without any special conditions.

In my check.c file, I define the special flag before and after the #include <check.h> file.  This guarantees the variable will be set to an initial value.

Its pretty fullproof and I have been using this style for several years now.




0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
duneramCommented:
I like that the method I have been using because it isolates all of the declaration headache down to one .h file.  I can include it in any source module and never have to worry about  whether or not its been 'extern' d.  Its pretty painless.

In your actual .c source module where you will be doing the real work on the variable(s) you simply, make sure you define the CHECK_C_IMPLEMENTED_HERE before you include the check.h file.  This will guarantee your variables will there ready for your use.  

It takes a little getting used to but once you put it in that style, you will never go back.
0
 
duneramCommented:
Its a style I invented.
0
 
alexoCommented:
duneram, are you sure you understand the difference between extern and extern "C"?
0
 
duneramCommented:
yep.... been using them for the last 13 years.... you don't have to use extern "c" but it makes life easier if you ever include your file from a .cpp file.  You don't have to go back and change your header...


0
 
duneramCommented:
alexo:  its a compiler issue... its how the compiler will generate symbols ....  by putting the "C" you guarantee the symbols will always be what you expected them to be.  


0
 
duneramCommented:
Plus I've studied advanced compiler theory and written 12 natural language compilers and one basic compiler... the basic compiler I wrote in assembler.
0
 
alexoCommented:
>> its a compiler issue... its how the compiler will generate symbols ....  by putting the "C" you guarantee the symbols will always be what you expected them to be.

Are you sure about that?

extern "C" declares functions with C linkage (no name mangling, etc.) it is only supported in C++ and has no effect on data items (except pointers to functions).

>> Plus I've studied advanced compiler theory [...]
And Clinton had sex with Lewinski.  Both of the statements are totally irrelevant to the discussion.

>> you don't have to use extern "c" but it makes life easier if you ever include your file from a .cpp file.  You don't have to go back and change your header...
Most C compilers will barf on extern "C".  All ABSI compliant C compilers will do so if run with a "strict ANSI compliance" flag or suchlike.  If you want C++ portablity write:

    #ifdef __cplusplus
    extern "C" {
    #endif

    /* Rest of header file goes here */

    #ifdef __cplusplus
    }
    #endif

Modulo include guards etc.
0
 
Answers2000Commented:
Ditto Alexo, just for completeness in ANSI C, duneram's version should be

#ifndef CHECK_H_HDR
#define CHECK_H_HDR
/* prevents it from being included twice */

#ifndef CHECK_C_IMPLEMENTED_HERE
   /* when we fall into this piece, it means someone else is trying to use it */
extern /* <<--- No "C" for ANSI C code */
#endif
short flag
#ifdef CHECK_C_IMPLEMENTED_HERE
              =  0  /* put your initialization code here */
                    
#endif
                    ; /* the ; always applies */
/* make sure you use the ';' above as it applies whether its an extern def or really being */
/* allocated here */


#endif  
 /* end of check.h */

This will of course really suck if you have multiple variables of different types...

Keele - BTW - ANSI C is the standard C language which will work on all compatible compilers.
0
 
duneramCommented:
IT may be harder to set up, but in the long run its easier to maintain.   Yeah I forgot to include the
#ifdef _cplusplus stuff as mentioned.


0
 
KeeleAuthor Commented:
Duneram, You have made a very good issue of this but I may need to make myself more clear. I am wanting to include only source code for functions in a .c file. I am not only talking about variables in this instance. I find what you all have written very interesting and a little more advanced than I am used to. I like the theory behind what you are accomplishing but my main question still remains unanswered. When I compile the .c file of different functions and NOT INCLUDING A MAIN(). The compiler pukes on me. "Unexpected end of file" and so on. Any other suggestions?
0
 
duneramCommented:
One of the things that used to nail me on the unexpected end of file was where if I had a .h file, if I didn't put an extra newline on the end of it, the compiler could not parse the
#endif

so at the bottom of my .h files, I would put something like this:

/*  End of h file */
/*****************/

Also check to make sure your { } pairs on functions are all there.  YOu may be missing a  ending } on a function somewhere

something like this:

int dog()
{

int cat ()
{
}

/* this would generate an error, because we never finished the 'dog' function. */
0
 
KeeleAuthor Commented:
But the unexpected EOF appears to be because there is no void main() fuction in my .c file. Here is how I initially tried to set up the file...

#include blah
#include blah
#include blah

extern void proc1()
{
}

extern void proc2()
{
}

/*end of file*/

and my .h file would define the externs

extern void proc1();
extern void proc2();

I must be doing something else wrong because I have double checked and triple checked my brackets.
0
 
KeeleAuthor Commented:
But the unexpected EOF appears to be because there is no void main() fuction in my .c file. Here is how I initially tried to set up the file...

#include blah
#include blah
#include blah

extern void proc1()
{
}

extern void proc2()
{
}

/*end of file*/

and my .h file would define the externs

extern void proc1();
extern void proc2();

I must be doing something else wrong because I have double checked and triple checked my brackets.
0
 
Answers2000Commented:
You wouldn't usually get an unexpected EOF for a missing main (most compiler's will give an error along the lines of "link error" or "missing external")

Looking at the code I suspect the reason for the error has to be the #include lines

Use quotes (") around the name if it's in your project's directory

Use greater-than less-than (<) around the name if it's in an include directory (example: the compiler standard libraries)

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

BTW extern on the function body's and prototypes is not necessary in standard ANSI C

0
 
duneramCommented:
In the part of the code where you are actually declaring the function, I don't think you need to use extern there...

extern tells the compiler that a particular symbol, be it a function or variable is implemented somewhere else, but not to cause an error if its encountered in the current source file.

so where you are doing:

extern void proc1()
{
}

you should just be doing

void proc1()
{
}


0
 
danny_pavCommented:
what compiler are you using?  You are getting an unexpected EOF?
please post the entire error message and give some compiler info.
0
 
danny_pavCommented:
OOPS, my bad, the title says you are using VC++ 5.  And you are compiling C code.  This may be your answer then:
check your precompiled header settings.
0
 
alexoCommented:
Keele, "unexpected end of file found" means that the compiler reached the end of a source file without resolving a construct.

Check the following possibilities:
* A source file does not end with a carriage return-linefeed pair.
* A function or structure definition may be missing a closing curly brace.
* A class, struct, enum or union definition may be missing a semicolon after its closing brace.
* A function call or expression may have mismatched parentheses.
* An #if directive evaluates to false without a corresponding closing #endif directive.
* Missisng quote at the end of a string.
* Missing right parentheses on a #define macro
* A C-style comment (i.e. /* ... */), is missing a closing asterisk-slash ( */ ).

>> extern void proc1() { /* ... */ }
Ditch the "extern" here.

Compile your source file with the /P switch, it will generate a .i file that contains the source after preprocessing.  Check it for errors like those I mentioned.
0
 
Answers2000Commented:
Keele, If you check for the stuff alexo mentioned make sure you check the .h (or other files) you #include too!
0
 
alexoCommented:
>>  If you check for the stuff alexo mentioned make sure you check the .h (or other files) you #include too!

No need, the /P switch is gonna take care of that...
0
 
Answers2000Commented:
Forgive incoherence, I meant in the original source.
0
 
KeeleAuthor Commented:
Well, Ok...looks like I have a few things to check. Thanks guys. I will get back to you to let you know if it worked.
0
 
raybCommented:
These answers are so complicated for such a simple question...  To make an 'int' public to all other sources, place the declaration in your implementation file, copy that declaration to your header file and put 'extern ' in front of it.

in your header:
extern int g_nValue;

in your implementation file:
int g_nValue= 0;

That's it.

0
 
alexoCommented:
>> I will get back to you to let you know if it worked.
Well???
0
 
Answers2000Commented:
rayb - I thought I said that about 1 month ago, but it's isn't what the Q'ster wanted.


0
 
raybCommented:
Ah...
Excuse me, while I remove my foot from my mouth.  :)

0
 
kinkajouCommented:
Keele says
>>The compiler pukes on me. "Unexpected end of file" and so on. Any other suggestions?

I apologise if this is already mentioned: I get the same error when "Precompiled Headers" is active in my MSVC project. So solve this, I go to the menu->project->settings..-> Select All configurations in the Settings For box. Select the C/C++ tab. Select Category: Precompiled Headers and check "Not Using Precompiled Headers".
0
 
KeeleAuthor Commented:
Well, I left a comment last week or so, but I guess it didn't post. I have tried it and the external variables work fine. The original question, however, was meant to be for making a function external....so I could a c file with only commonly used functions. But, I think I have wasted all your time here, I apologize for that.
Thanks for your help.


0
 
NullTerminatorCommented:
Functions in a .c source file are all externally visible by default. You don't have to do anything but include them in the link.  To make them local to the module where they are defined make them static functions.

The end of file error is a seperate issue entirely,  guaranteed to be a typo, or missing crlf at the end of a preprocessor statement.  You may have mismatched braces, or a brace within a quote somewhere.  Does the warning say EOF found looking for " something?"
0
 
RONSLOWCommented:
put your function defintions (bodies) in separate .c files.  Do not use extern on function definitions.

put function declarations (so that other functions can use them and compile ok) in a .h file (usually you'd put several related function declarations in the one .h file).   Do not use extern on function declarations.

#include the relevant .h file in all .c files that use your functions.  This is required so that the .c file will compile OK (and won't make assumptions about return types etc).

ensure that the .c files are included in you project so that they all get linked together with the .c file that has your main() in it.

NOTE: Simply writing a function _without_ a 'static' will make expose it for linking.  The declaration in the .h file is only needed at compiler time.

If using VC, then turn off precompiled headers for you .c files (or for the whole project) unless you are using Windows api or MFC.  Alternatively, #include "stdafx.h" in your .c files.  If you have precompiled headers enabled, then VC will scan your .c file looking for a #include "stdafx.h" and complain if it doesn't find it (this is because of the way precompiled headers work .. the precompiled header replaces all lines upto and includeing the #include "stdafx.h", so it there is no such line there, it gets confused).

NOTE: use #ifdef/#define/#endif in .h files to avoid things being multiply declared, or your compiler from getting in a loop.  Avoid putting unnecessary #include's in .h files (as opposed to .c files).

0
 
KeeleAuthor Commented:
Thanks Ronslow, Finally a simple, straight forward and to the point answer. Great answer.

Keele
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 9
  • 6
  • 6
  • +7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now