The C language extern acts on pointers and Arrays

Source: Internet
Author: User

The following is the test environment:

GCC 4.3.2-1-1

GNU/Linux Debian 5.0

(I have no experience using csdn blogs at the beginning. Due to the long debugging time in the middle, I forgot to back up the data. I just finished writing it and sent it quickly. A look, no; look again, still no. Get angry and rewrite an article. We hope that readers can back up data in a timely manner based on this recognition. :-)

1. extern and static

Extern is visible to variables and function declarations during compilation, that is, it tells the compiler: "Dude, although I have no definition in this file, it is defined elsewhere. You have to let me go ". For the purpose of inspection and use, no definition is allowed.

Both functions and variables are extern by default, which is visible to all files during the link. What's more, static and extern are defined by default, which leads to the inevitability of explicit declaration of extern. This will be analyzed in detail later.

 

Static, literally a static qualifier, which has three effects on three occasions:

A. When acting on a local variable, the value of the function remains continuous for the lifetime. How can we understand it? A common but inaccurate expression: It is initialized once, And the last result will be continued each time the function is called. For example:

1 # include
<Stdio. h>
2
3 # define count
3
4StaticStat_count = count-
1;
5IntStat ()
6 {
7StaticCount = count;
8
9 count --;
10 printf ("the result in n. o.
% D invacation:
% D./N ", stat_count, count );
11ReturnCount;
12}
13IntMain ()
14 {
15While(STAT ())
16 stat_count --;
17Return0;
18}

 

The result in n. o. 2 invacation: 2.
The result in n. o. 1 invacation: 1.
The result in n. o. 0 invacation: 0.

 

B. It acts on global variables only in this file. Its relative value is extern. The specific comparison will be analyzed later.

C. Act on the function, which is only called by other functions in this file. The default values of functions and variables are extern. This document does not focus on specific analysis.

 

Abstract points have three roles:

Hide global visibility;

Keep the variable content persistent;

The default value is 0.

For more information, see:

Role of Steven's technical blog in static

Http://www.cnblogs.com/dc10101/archive/2007/08/22/865556.html

 

2. extern global variables

Modern compilers all compile by file. during compilation, each file checks for syntax errors independently. Each global variable is transparent to each other, and the visible domain is in this file.

Therefore, even if multiple files have multiple definitions, no error is reported, but all global variables are saved in a symbol table during the link to locate the symbols. Therefore, the error is also reported in the Link phase.

Have you noticed? Link error

 

That is to say, visibility is extended during linking, and the compilation phase is limited to this file.

 

Type ID; by default, variables and functions are extern, that is, all files are visible.


But the default definition is not only declaration, but also definition. The C language specifies that an identifier can have multiple declarations, but must have only one definition.

Declaration to let the compiler know which symbols and types are available, so that the compiler has a certain degree of judgment awareness (for example, type check, initialization check, and definition check ).

Therefore, the default type ID is displayed in multiple files, that is, multiple definitions. If multiple files share one symbol, you need to use extern to explicitly specify the declaration.

Extern type ID; it is only a declaration. It must be defined separately and be defined in other files.


Let's take a look at how the compiler limits it (you can only look at the red part ):

1 ),
Extern char * str_ptr;

Str_ptr = "ABCD/0 ";

GCC Compilation:

Test. c :(. Text + 0x13): Undefined reference to 'str _ PTR'

2 ),
Extern char * str_ptr;

Char * str_ptr = "ABCD/0 ";

GCC Compilation:

Test. C: 13: Error: Declaration of 'str _ PTR'
No linkage follows extern Declaration
Test. C: 12: Error: previous declaration of 'str _ PTR 'was here

3 ),

Extern
Char * str_ptr = "ABCD/0 ";

GCC Compilation:

Test. C: 12: Error: 'str _ PTR 'has both 'extern' and initializer

4 ),

Char * str_ptr = "ABCD/0 ";
Extern char * str_ptr;

GCC Compilation:

Test. C: 13: Error: extern declaration of 'str _ PTR 'follows declaration
No linkage
Test. C: 12: Error: previous definition of 'str _ PTR 'was here

 

3. Apply extern to pointer

 

Perform the following tests:

File 1

1 /*
2 * file: test_declaration.c
3 * purpose: Declaration of array used by test_extern.c
4 * maninter: hilyhoo at gmail.com
5 */
6 # include
<Stdio. h>
7
8CharStr_ptr [] =
"ABCD/0 ";
9CharStr_array [] =
"ABCD/0 ";
10
11IntNULL ()
12 {
13 1;
14Return0;
15}

File 2

1 /*
2 * file: test_extern.c
3 * input: None
4 * rerult: Print 'C' and report a segment Error
5 * purpose: Test extern point with define Array
6 * maninter: hilyhoo at gmail.com
7 */
8 # include
<Stdio. h>
9
10IntMain ()
11 {
12Extern Char* Str_ptr;
13Extern CharStr_array [];
14
15 printf ("extern pointer resrult:
% C/N ", str_array [2]);
16 printf ("extern array resrult:
% C/N ", str_ptr [2]);
17
18Return0;
19}


GCC compilation and running:

Gcc-G test_extern.c test_decleration.c

./A. Out

Extern pointer resrult: c
Segment Error


GDB debugging:

(GDB) B Main
Breakpoint 1 at 0x80483c1: file test. C, line 15.
(GDB) P str_ptr
$1 = 0x64636261 <address 0x64636261 out of bounds>
(GDB) P str_array
$2 = 0x804961a "ABCD"
(GDB) r
Starting program:/home/hilyhoo/c/a. Out

Breakpoint 1, main () at test. C: 15
15 null ();
(GDB) S
NULL () at dec. C: 14
Warning: source file is more recent than executable.
14}
(GDB) P str_ptr
$3 = "ABCD/000"

(GDB) x str_ptr
0x8049614 <str_ptr>: 0x64636261
(GDB) S
Line number 15 out of range; Dec. C has 14 lines.
(GDB) S
Main () at test. C: 17
17 printf ("extern pointer resrult: % C/N", str_array [2]);
(GDB) x str_array
0x804961a <str_array>: 0x64636261
(GDB) S
Extern pointer resrult: c
18 printf ("extern array resrult: % C/N", str_ptr [2]);
(GDB) x str_ptr
0x8049614 <str_ptr>: 0x64636261
(GDB) S

Program received signal SIGSEGV, segmentation fault.
0x080483e8 in main () at test. C: 18
18 printf ("extern array resrult: % C/N", str_ptr [2]);

 

The above example shows:

CharStr_ptr [] =
"ABCD/0 ";

Extern Char* Str_ptr;
The two files are independent during compilation, and the links are declared as follows:

Definition: str_ptr, array, address 0x8049614, content "ABCD/0", hexadecimal 0x61, 0x62, 0x63, 0x64

Link: str_ptr, pointer, address 0x8049614, long integer, hexadecimal 0x64636261

Str_ptr [2], * (str_ptr + 2), that is, * (0x64636263), no access permission, that is, a disconnection error is reported.

 

Str_ptr => "ABCD"

0x64

0x63

0x62

0x8049614 => 0x61

......

0x64

0x63

0x62

Str_ptr + 2 => 0x63

* (Str_ptr + 2) ==>?


We can see that:

The pointer symbol is the address of the address;

Array symbol, corresponding to the entire array; if it is used as the name of a one-dimensional array variable, it is the address of its first unit.

1)

An array is just a symbol. When a parameter is used as a parameter, the first address of the array is pressed into the stack due to the pressure of the form parameter. That is, the first address is stored in a space and changed to a pointer; the multi-dimensional array is interpreted as a pointer by the compiler.

Otherwise, the array name does not occupy a separate space. In the symbol table, it is a symbol. The address is the first address of the array, and the content is the content of the first unit.

2)

When defining pointers, allocate a space (our system is 32-bit, 4 bytes), which is the address of the pointing unit.

 

 

3. Summary

1) if extern is explicitly declared, it cannot be defined in the current file and must be defined in other linked files.

(In the GCC compiler, it is said that some compilers are different. For example, you can use

Extern type id = initialize;

Therefore, I am afraid to mislead the readers .)

 

2) the pointer and array are quite different, but in general, the array will change to pointer usage, for example:

Id [offset], the compiler will interpret it as * (ID + offset), so it is generally used to almost feel the difference.

Related Article

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.