extern usage C and C + + mixed __c++

Source: Internet
Author: User
Tags function definition function examples function prototype visibility

1. Declaring external variables

Modern compilers are generally compiled by file, so at compile time, the global variables defined in each file are

Transparent to each other, that is, at compile time, the visible domain of the global variable is limited to the inside of the file. Here's a simple example. Create a project that contains A.cpp and B.cpp two simple C + + source files:

A.cpp

int i;

void Main ()

{

}

B.cpp

int i;

These two files are extremely simple, in A.cpp we define a global variable I, and in B we also define a global variable i.

We compile a and B separately, all can be compiled normally, but when the link, but there are errors, error prompts as follows:

Linking ...

B.obj:error LNK2005: "int i" (? i@@3ha) already defined in A.obj

Debug/a.exe:fatal error Lnk1169:one or more multiply defined symbols found

Error executing link.exe.

A.exe-2 error (s), 0 warning (s)

That is, in the compile phase, the global variables defined in each file are transparent to each other, and when you compile a, you do not perceive the I in B, and likewise, when you compile B, you do not perceive that a is defined by I.

But in the link phase, the contents of each file are "integrated", so if you have the same global variable name defined in some files, there will be an error at this point, which is the duplicate-defined error indicated above.

Therefore, the names of the global variables defined in each file cannot be the same.

In the link phase, the contents of each file (actually the generated obj file) are merged together, so that the global variable defined in a file, after the link is complete, its visible range is extended to the entire program.

Thus, it is reasonable to say that a global variable defined in a file can be used anywhere in the entire program, for example, if a global variable is defined in file A, then the variable should be available in file B. Modify our program to verify:

A.cpp

void Main ()

{

i = 100; An attempt was made to use a global variable defined in B

}

B.cpp

int i;

The results of the compilation are as follows:

Compiling ...

A.cpp

C:\Documents and settings\wangjian\ Desktop \try extern\a.cpp (5): Error C2065: ' I ': undeclared identifier

Error executing cl.exe.

A.obj-1 error (s), 0 warning (s)

Compilation error.

This error is expected because the visibility of the global variables defined in the file extends to the entire program after the link is complete, and in the compile phase, their visibility is still limited to their respective files.

The compiler's gaze is not long enough for the compiler to realize that a variable symbol, although not defined in this file, may be defined in other files.

Although the compiler is not far-sighted, we can give it a hint to help solve the problem that appears above. This is the role of extern.

The principle of extern is simply to tell the compiler: "The file you are compiling now has an identifier that is not defined in this file, but it is a global variable defined in another file that you want to release." ”

We add the extern keyword to the error program above:

A.cpp

  extern int i;

void Main ()

{

i = 100; An attempt was made to use a global variable defined in B

}

B.cpp

int i;

Smoothly through compiling, linking. function

  extern function 1

Common extern is placed in front of a function as part of a function declaration, so the keyword extern of C language plays a role in the declaration of a function.

Answer and Analysis:

If the declaration of a function has the keyword extern, it simply implies that the function may be defined in another source file, with no other effect. That is, there are no obvious differences between the following two function declarations:

extern int f (); and int f ();

Of course, the use of this is in the program to replace the include "*.h" to declare functions, in some complex projects, I am more accustomed to all the function declarations before adding extern decoration.

  extern function 2

When the function provider modifies the function prototype unilaterally, the compiler will not make an error if the user does not knowingly continue with the original extern declaration. However, in the running process, because less or more input parameters, often cause system errors, this situation should be how to solve.

Answer and Analysis:

Currently, the industry does not have a perfect solution for this situation, the common practice is that the provider in its own xxx_pub.h to provide a declaration of the external interface, and then the caller include the header file, thus eliminating the step of extern. To avoid this error.

The sword has two fronts, for the application of extern, different occasions should choose a different approach.

  extern "C"

When using C functions in C + + environments, it is often possible for the compiler to find the C function definition in the OBJ module, which causes the link to fail, and how it should be resolved.

Answer and Analysis:

The C + + language is compiled in order to solve the problem of function polymorphism, the function names and parameters will be combined to generate a middle of the functions of the name, and the C language will not, so will cause the link can not find the corresponding function, at this time the C function needs to use extern "C" for the link designation, which tells the compiler, Please keep my name and don't give me the middle function name for the link.

Here is a standard notation:

On the head of the. h file

#ifdef __cplusplus

#if __cplusplus

extern "C" {

#endif

#endif/* __cplusplus * *

...

...

where the. h file ends

#ifdef __cplusplus

#if __cplusplus

}

#endif

#endif/* __cplusplus * *

  Deep Exploration of extern C in C + +

The C + + language was originally created "A better C", but this does not mean that the C-language-like global variables and functions in C + + are compiled and connected in exactly the same way as the C language. As a language intended to be compatible with C, C + + retains some of the characteristics of the procedural language (known as "not completely object-oriented"), so it can define global variables and functions that do not belong to any class. But, after all, C + + is an object-oriented programming language, in order to support the overloading of functions, C + + for global functions of the processing mode and C are significantly different.

2. From the standard header document

An enterprise has given the following interview questions:

Interview questions

Why standard header files have structures similar to the following.

#ifndef __incvxworksh

#define __incvxworksh

#ifdef __cplusplus

extern "C" {

#endif

/*...*/

#ifdef __cplusplus

}

#endif

#endif/* __incvxworksh * *

Analysis

Obviously, the role of the compiled macro "#ifndef __incvxworksh, #define __incvxworksh, #endif" In the header file is to prevent the header file from being repeatedly referenced.

So

#ifdef __cplusplus

extern "C" {

#endif

#ifdef __cplusplus

}

#endif

What is the role of it. We will come in the following one by one ways.

  3. Deep disclosure of extern "C"

The extern "C" contains a double meaning, literally: First, the object modified by it is "extern"; second, the target it modifies is "C". Let's take a detailed interpretation of this twofold meaning.

A function or variable that is qualified by extern "C" is an extern type;

extern is a keyword that indicates the scope (visibility) of functions and global variables in the C + + language, which tells the compiler that its declared functions and variables can be used in this module or in other modules. Remember the following statement:

extern int A;

is simply a declaration of a variable that is not defining variable A and allocating no memory space for a. Variable A can only be defined once as a global variable in all modules, otherwise there will be a connection error.

Typically, the module's header file provides the keyword extern declaration for functions and global variables that are referenced by this module to other modules. For example, if module B wants to refer to the global variables and functions defined in module A, just include the header file for module A. In this way, when a function in module A is called in Module B, module B cannot find the function in the compile phase, but it does not complain; it will find this function in the connection phase from the object code generated by module a compilation.

The keyword that corresponds to extern is static, and global variables and functions that are decorated with it can only be used in this module. Therefore, a function or variable can only be used by this module, it cannot be decorated by extern "C".

The variables and functions that are decorated by extern "C" are compiled and connected according to the C language;

How to compile without extern "C" declaration

First look at C + + in C-like functions are compiled.

As an object-oriented language, C + + supports function overloading, while programming language C does not support it. A function is compiled by C + + in a symbol library with a different name than the C language. For example, suppose the prototype of a function is:

void foo (int x, int y);

The function is compiled by the C compiler in the symbol library with the name _foo, and the C + + compiler produces names like _foo_int_int (different compilers may produce different names, but all use the same mechanism, the resulting new name is called "Mangled Name").

_foo_int_int Such a name contains the function name, the number of function parameters and type information, C + + is to rely on this mechanism to implement the function overload. For example, in C + +, the function void foo (int x, int y) is not the same as the symbol generated by the compilation of void foo (int x, float y), which is _foo_int_float.

Similarly, variables in C + + support class member variables and global variables in addition to local variables. The class member variable of the program that the user writes may have the same name as the global variable, and we use the "." to differentiate. In essence, the compiler, when compiling, is similar to the processing of a function, and a unique name for a variable in a class that is different from the name of a global variable with the same name as the user program.

Connection mode without extern "C" declaration

Suppose in C + +, the header file for module A is as follows:

Module a header file moduleA.h

#ifndef module_a_h

#define Module_a_h

int foo (int x, int y);

#endif

Reference this function in module B:

Module B implementation file ModuleB.cpp

#include "ModuleA.h"

Foo (2,3);

In fact, in the connection phase, the connector looks for symbols such as _foo_int_int from the target file Modulea.obj generated by module A.

How to compile and connect after the extern "C" declaration

After adding the extern "C" declaration, module A's header file becomes:

Module a header file moduleA.h

#ifndef module_a_h

#define Module_a_h

extern "C" int foo (int x, int y);

#endif

The Foo (2,3) is still called in the implementation file of Module B, and the result is:

(1) When the module a compiles the object code of Foo, it does not specially deal with its name, and adopts the method of C language;

(2) The connector is looking for an unmodified symbol name _foo when looking for the Foo (2,3) call for the target code of Module B.

If the function in module a declares that Foo is an extern "C" type, and Module B contains extern int foo (int x, int y), module B cannot find the function in module A and vice versa.

So, you can generalize the true purpose of the declaration of extern "C" in one sentence (the birth of any grammatical feature in any language is not random, it comes from the demand-driven of the real world.) When we think about problems, we can't just stay in the language, and ask why it does it, what the motivation is, so that we can understand a lot more deeply:

Implement mixed programming with C + + and other languages.

Understand the C + + in the establishment of extern "C" motivation, we are below to specifically analyze the extern "C" the usual use of skills.

4.extern "C" idiomatic method

(1) in C + + reference to the functions and variables, in the C language header file (assumed to be cExample.h), you need to do the following processing:

extern "C"

{

#include "cExample.h"

}

In the C language header file, the external function can only be specified as an extern type, and the extern "C" declaration is not supported in C language, and a compilation syntax error occurs when the. c file contains extern "C".

The author of C + + reference to quote the example of the project contains three files of the source code as follows:

/* C Language header file: cExample.h * *

#ifndef C_example_h

#define C_example_h

extern int Add (int x,int y);

#endif

/* C language Implementation file: CEXAMPLE.C * *

#include "cExample.h"

int add (int x, int y)

{

return x + y;

}

C + + implementation file, calling Add:cppFile.cpp

extern "C"

{

#include "cExample.h"

}

int main (int argc, char* argv[])

{

Add (2,3);

return 0;

}

If C + + calls a. dll written in C, you should add extern "C" {} When you include the header file for the. dll or when declaring an interface function.

(2) When referencing functions and variables in C + + language, the header file of C + + must be added extern "C", but in C language it is not possible to refer directly to the header file that declares extern "C", only the extern "C" defined in C + + should be function is declared as an extern type.

The author of the C reference + + function Examples of the project included in the three files of the source code are as follows:

C + + header file CppExample.h

#ifndef Cpp_example_h

#define Cpp_example_h

extern "C" int Add (int x, int y);

#endif

C + + implementation file CppExample.cpp

#include "cppExample.h"

int add (int x, int y)

{

return x + y;

}

/* C Implementation file cfile.c

/* This will compile error: #include "cExample.h" * *

extern int Add (int x, int y);

int main (int argc, char* argv[])

{

Add (2, 3);

return 0;

}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.