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 declarationbuffer[]
.
-
But I can't figure out why we can't access this array using
*buffer
and we can access it usingbuffer[]
. -
Would someone please explain to me what is the difference between these two types?
source to share
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.
source to share
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.
source to share
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.
source to share