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

I have read below some of the information in the Microsoft article,

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

The text below provides an example of a common programming error, that is, confusion between an array and a pointer declaration: Consider an application divided into several modules. In one module, declare an array like this:

  signed char buffer[100];

      

In another module, declare the following variables for accessing the array:

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

      

If you look at the code in the CodeView debugger, it means that the declaration *buffer

creates a different address than the declaration buffer[]

.

  • But I can't figure out why we can't access this array using *buffer

    and we can access it using buffer[]

    .

  • Would someone please explain to me what is the difference between these two types?

+3


source to share


5 answers


See these questions in the list of frequently asked questions:



+1


source


extern signed char buffer[];

      

is a piece of memory in which it has an address.



extern signed char *buffer;

      

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

+3


source


Difference between

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

      

matches what you saw when you have

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

      

in function.

I see the following differences:

Difference 1

If you have:

extern signed char *buffer;

      

you can use:

buffer = malloc(10);

      

If you have:

extern signed char buffer[]; 

      

you cannot do this.

Difference 2

In the first case, it buffer

is possible that it will be NULL. In the second case, this is not the case.

Difference 3

&buffer

lead to different types. For example, you can use:

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

      

in the first case, but you can't use that in the second case. For the &buffer+1

second case to work, you need to know the size of the array.

+1


source


This question has more to do with the C linker than the C language.

While there is a context where signed char *buffer

u signed char buffer[]

mean the same thing, is extern

not one of them. Usage extern

asks the compiler to defer resolving the external definition to the linker. Linker needs to be very specific about the difference between pointers and arrays, since they have different structures in memory and cannot be considered interchangeable.

Note that although these declarations differ from the linker, they do not change what the programmer might do with such an external array: in both cases, you have no access to the size of the declared array (i.e. 100), the syntax for accessing the elements is the array remains unchanged and the pointer arithmetic remains unchanged.

+1


source


In one module, define an array of signed char

size 100

named buffer

. This object will use 100 bytes of memory:

signed char buffer[100];

      

In another module, declare buffer

something else, a pointer to signed char

, that is, 4 or 8 bytes of memory, which can contain an array address or one char

.

extern signed char *buffer;

      

The compiler only knows one module at a time, so it cannot check if this declaration matches the actual definition . It compiles the code sequentially with this declaration emitting machine code that refers to an external symbol buffer

to be resolved at connection time.

At the point of reference, the linker is not aware of types, it only depends on names. Therefore, it resolves references to buffer

from one module with the actual address of a definition from another module.

At runtime, you get undefined behavior, because one module uses buffer

as the array signed char

that it is, and the other loads the pointer value from the same address, completely interpreting the bytes differently.

Declarations refer to header files and should always be included in the source file , which actually defines the object declared in the header.

+1


source







All Articles