简体   繁体   中英

In C language, What is the difference between extern buffer[] and extern *buffer?

I read the below piece of information in a microsoft article;

https://support.microsoft.com/en-us/kb/44463

The text below presents an example of a common programming mistake, that is, confusing an array and a pointer declaration: Consider an application divided into several modules. In one module, declare an array as follows:

  signed char buffer[100]; 

In another module, declare the following variables to access the array:

  extern signed char *buffer; // FAILS extern signed char buffer[]; // WORKS 

If you view the code in the CodeView debugger, it indicates that the *buffer declaration produces a different address than the buffer[] declaration does.

  1. But I can't understand why we cannot access that array using *buffer and we can access it using buffer[] .

  2. Someone please explain me what is the difference between those two types?

extern signed char buffer[];

is a chunk of memory that has an address.

extern signed char *buffer;

is a variable that may or may not point to a chunk of memory - it's a variable that contains an address that may or may not be valid.

The differences between

extern signed char *buffer;
extern signed char buffer[]; 

is the same as you would see when you have

signed char *buffer;
signed char buffer[100];

in a function.

I see the following differences:

Difference 1

When you have:

extern signed char *buffer;

you can use:

buffer = malloc(10);

When you have:

extern signed char buffer[]; 

you cannot do that.

Difference 2

In the first case, it is possible for buffer to be NULL. In the second case, it is not.

Difference 3

&buffer result in different types. For example, you can use:

printf("pointer 1: %p\n", &buffer+1);

in the first case but you cannot use that in the second case. For &buffer+1 to work in the second case, you'll have to know the size of the array.

This question is more about C linker than about C language.

Although there is a context where signed char *buffer and signed char buffer[] mean the same thing, extern is not one of them. Using extern asks the compiler to defer resolving of the external definition to linker. Linker has to be very particular about the difference between pointers and arrays, because the two have different structure in memory, and cannot be treated interchangeably.

Note that although these declarations are different to the linker, they do not change what a programmer could do with such an external array: in both cases you have no access to the size of the declared array (ie 100), the syntax to access array elements stays the same, and the pointer arithmetic remains the same.

In one module, you define an array of signed char of size 100 named buffer . This object will use 100 bytes of memory:

signed char buffer[100];

In another module, you declare buffer to be something else, a pointer to signed char , that is 4 or 8 bytes of memory that may hold the address of an array or that of a single char .

extern signed char *buffer;

The compiler only knows one module at a time, so it cannot check whether this declaration is consistent with the actual definition . It compiles code consistently with this declaration, emitting machine code that refers to an external symbol buffer that will be resolved at link time.

At link time, the linker does not know about types, it only relies on names. Therefore it resolves the references to buffer from one module with the actual address of the definition from the other module.

At runtime, you get undefined behaviour, because one module uses buffer as an array of signed char , which it is, and the other loads the value of a pointer from the same address, interpreting the bytes completely differently.

Declarations belong in header files and should always be included in the source file that actually defines the object declared in the header.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM