ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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?
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.
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.
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
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.
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.
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.
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.