Solved

Extern in DevStudio 5.0

Posted on 1998-08-28
34
231 Views
Last Modified: 2010-04-15
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
Comment
Question by:Keele
  • 9
  • 6
  • 6
  • +7
34 Comments
 
LVL 2

Expert Comment

by:kellyjj
ID: 1252384
what kind of errors/problems are you getting??  
0
 
LVL 8

Expert Comment

by:Answers2000
ID: 1252385
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
 
LVL 2

Expert Comment

by:duneram
ID: 1252386
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
 
LVL 2

Expert Comment

by:duneram
ID: 1252387
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
 
LVL 2

Expert Comment

by:duneram
ID: 1252388
Its a style I invented.
0
 
LVL 11

Expert Comment

by:alexo
ID: 1252389
duneram, are you sure you understand the difference between extern and extern "C"?
0
 
LVL 2

Expert Comment

by:duneram
ID: 1252390
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
 
LVL 2

Expert Comment

by:duneram
ID: 1252391
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
 
LVL 2

Expert Comment

by:duneram
ID: 1252392
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
 
LVL 11

Expert Comment

by:alexo
ID: 1252393
>> 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
 
LVL 8

Expert Comment

by:Answers2000
ID: 1252394
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
 
LVL 2

Expert Comment

by:duneram
ID: 1252395
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
 

Author Comment

by:Keele
ID: 1252396
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
 
LVL 2

Expert Comment

by:duneram
ID: 1252397
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
 

Author Comment

by:Keele
ID: 1252398
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
 

Author Comment

by:Keele
ID: 1252399
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
 
LVL 8

Expert Comment

by:Answers2000
ID: 1252400
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
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 2

Expert Comment

by:duneram
ID: 1252401
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
 
LVL 3

Expert Comment

by:danny_pav
ID: 1252402
what compiler are you using?  You are getting an unexpected EOF?
please post the entire error message and give some compiler info.
0
 
LVL 3

Expert Comment

by:danny_pav
ID: 1252403
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
 
LVL 11

Expert Comment

by:alexo
ID: 1252404
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
 
LVL 8

Expert Comment

by:Answers2000
ID: 1252405
Keele, If you check for the stuff alexo mentioned make sure you check the .h (or other files) you #include too!
0
 
LVL 11

Expert Comment

by:alexo
ID: 1252406
>>  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
 
LVL 8

Expert Comment

by:Answers2000
ID: 1252407
Forgive incoherence, I meant in the original source.
0
 

Author Comment

by:Keele
ID: 1252408
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
 
LVL 2

Expert Comment

by:rayb
ID: 1252409
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
 
LVL 11

Expert Comment

by:alexo
ID: 1252410
>> I will get back to you to let you know if it worked.
Well???
0
 
LVL 8

Expert Comment

by:Answers2000
ID: 1252411
rayb - I thought I said that about 1 month ago, but it's isn't what the Q'ster wanted.


0
 
LVL 2

Expert Comment

by:rayb
ID: 1252412
Ah...
Excuse me, while I remove my foot from my mouth.  :)

0
 
LVL 2

Expert Comment

by:kinkajou
ID: 1252413
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
 

Author Comment

by:Keele
ID: 1252414
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
 
LVL 3

Expert Comment

by:NullTerminator
ID: 1252415
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
 
LVL 10

Accepted Solution

by:
RONSLOW earned 100 total points
ID: 1252416
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
 

Author Comment

by:Keele
ID: 1252417
Thanks Ronslow, Finally a simple, straight forward and to the point answer. Great answer.

Keele
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now