LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-08-2011, 10:33 AM   #1
dspjm
Member
 
Registered: Dec 2010
Distribution: Scientific Linux Slackware
Posts: 91

Rep: Reputation: 2
Why does it need an "extern"


In this function
Code:
static void start_main(void)
{
    int retval;
    extern int openbios(void);
    extern void init_exceptions(void);

    /* Save startup context, so we can refer to it later.
     * We have to keep it in physical address since we will relocate. */
    __boot_ctx = virt_to_phys(__context);

    init_exceptions();
    /* Start the real fun */
    retval = openbios();

    /* Pass return value to startup context. Bootloader may see it. */
    boot_ctx->eax = retval;

    /* Returning from here should jump to __exit_context */
    __context = boot_ctx;
}
the red part has a definition in openbios.c. In my memory, although the function is in another source file, there doesn't need an extern to use a function, the extern is needed just when you use a global variable in another source file. Where is my mistake?

Thanks in advance.
 
Old 09-08-2011, 11:02 AM   #2
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
More than likely (I haven't verified this) the openbios() function prototype is *not* declared within a header file. Thus when a module wishes to call this function, it is best to "forward declare" the function with the "extern" attribute so that the compiler will know what this function prototype should be, and that it can expect to find this function when the linking of the application takes place. Otherwise, the compiler will issue a warning that the function's prototype is unknown.

IIRC, the following code should simulate the issue:
Code:
int main()
{
   extern int function();

   /* call function() here */
   int value = function();

   return 0;
}

/* implement function() here */
int function()
{
   return 0;
}
Remove (or comment out) the statement with the "extern", and verify how the compiler reacts.

Last edited by dwhitney67; 09-08-2011 at 11:04 AM.
 
Old 09-08-2011, 11:40 AM   #3
dspjm
Member
 
Registered: Dec 2010
Distribution: Scientific Linux Slackware
Posts: 91

Original Poster
Rep: Reputation: 2
Quote:
Originally Posted by dwhitney67 View Post
More than likely (I haven't verified this) the openbios() function prototype is *not* declared within a header file. Thus when a module wishes to call this function, it is best to "forward declare" the function with the "extern" attribute so that the compiler will know what this function prototype should be, and that it can expect to find this function when the linking of the application takes place. Otherwise, the compiler will issue a warning that the function's prototype is unknown.

IIRC, the following code should simulate the issue:
Code:
int main()
{
   extern int function();

   /* call function() here */
   int value = function();

   return 0;
}

/* implement function() here */
int function()
{
   return 0;
}
Remove (or comment out) the statement with the "extern", and verify how the compiler reacts.
I don't think that is the problem, while, in my example, it didn't include the declaration of openbios(), but as your suggestion, I did wrote a program and comment the extern part, but the complier didn't say anything, even when I put the function() definition into another file, nothing happened, so... there must be another reason for the extern.
 
Old 09-08-2011, 03:03 PM   #4
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Quote:
Originally Posted by dspjm View Post
I don't think that is the problem...
There is no problem... and trust me, my description of the purpose of the extern is correct, although I'm sure there's a better "text book" answer available elsewhere.

Quote:
Originally Posted by dspjm View Post
I did wrote a program and comment the extern part, but the complier didn't say anything...
Recompile your test program using the -Wall option. Try with the extern statement, and try again without it.
 
Old 09-08-2011, 03:32 PM   #5
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Even if the function was declared in a header file, its declaration would still be incorrect if it didn't specify extern. It isn't part of the C source seen by the compiler, so the reference to it cannot be resolved until link time. Any symbol (function or variable) not resolvable by the compiler needs to be declared as extern. As a function, the declaration should also specify the parameter list and return type.

--- rod.
 
Old 09-08-2011, 04:11 PM   #6
Peverel
Member
 
Registered: May 2009
Location: Chelmsford, England
Distribution: OpenSuse 12.2 and 13.2, Leap 4.2
Posts: 128

Rep: Reputation: 24
A small addition to theNbomr's correct answer. With older compilers one could get away without the declaration because an undeclared function was assumed to return int. However, this was a fruitful source of error. Suppose such a function really returned a float and was assigned to a float variable. With an extern declaration, correct code would be generated; without, the returned value (or part of it) would be treated as int and converted to float, leading to a very obscure run-time error.
 
Old 09-08-2011, 09:20 PM   #7
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by theNbomr View Post
Even if the function was declared in a header file, its declaration would still be incorrect if it didn't specify extern. It isn't part of the C source seen by the compiler, so the reference to it cannot be resolved until link time. Any symbol (function or variable) not resolvable by the compiler needs to be declared as extern.
That's not entirely true, at least in C99:
Quote:
Originally Posted by 6.2.2.5 (N1256)
If the declaration of an identifier for a function has no storage-class specifier, its linkage
is determined exactly as if it were declared with the storage-class specifier extern. If
the declaration of an identifier for an object has file scope and no storage-class specifier,
its linkage is external.
Kevin Barry
 
Old 09-09-2011, 07:53 AM   #8
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
I stand corrected. Thanks for pointing that out.
--- rod.
 
Old 09-09-2011, 09:21 AM   #9
AnanthaP
Member
 
Registered: Jul 2004
Location: Chennai, India
Posts: 952

Rep: Reputation: 217Reputation: 217Reputation: 217
In practice, extern is usually needed when the referred function is external to the source file in which used.

OK
 
Old 09-09-2011, 09:52 AM   #10
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by AnanthaP View Post
In practice, extern is usually needed when the referred function is external to the source file in which used.

OK
In my experience, it's rarely (if ever) necessary for functions when using gcc, even with shared libraries.
Kevin Barry
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Calling emacs experts: Can indentation ignore extern "C" { .. }? JohnGraham Programming 4 08-01-2011 03:29 PM
Extern "c" declaration for a function is giving error. manas_sem Programming 3 06-28-2007 12:15 PM
expected ';' before "extern" lucky6969b Programming 5 12-23-2005 09:55 PM
extern "C" and static data type problem with g++ vtluu Red Hat 1 05-21-2004 10:45 AM
extern "C" and static data type problem with g++ vtluu Programming 2 04-28-2004 05:10 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 01:42 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration