Если у вас есть:
extern void some_function(char * s, int l);
void do_it(void) {
char str[] = "I'm doing it!";
some_function(str, sizeof(str) );
}
Это может превратиться в нечто вроде (в псевдо-ассм для обработанного процессора):
.data
local .do_it.str ; The contents of str are stored in a static variable
.text ; text is where code lives within the executable or object file
do_it:
subtract (sizeof(str)) from stack_pointer ; This reserves the space for str, sizeof(str)
; and a pointer to str on the stack
copy (sizeof(str)) bytes from .do_it.str to [stack_pointer+0] ; this loads the local variable
; using to the memory at the top of the stack
; This copy can be a function call or inline code.
push sizeof(str) ; push second argument first
push stack_pointer+4 ; assuming that we have 4 byte integers,
; this is the memory just on the other side of where we pushed
; sizeof(str), which is where str[0] ended up
call some_function
add (sizeof(str)+8) to stack_pointer ; reclaim the memory used by str, sizeof(str),
; and the pointer to str from the stack
return
Из этого вы можете видеть, что ваше предположение о том, как создается локальная переменная str, не совсем верно, но это не всегда так эффективно, как могло бы быть.
Если вы сделали
void do_it(void) {
static str[] = "I'm doing it!";
Тогда компилятор не зарезервирует место в стеке для строки, а затем скопирует ее в стек. Если some_function изменяет содержимое str, то следующий (или одновременный) вызов do_it
(в том же процессе) будет использовать измененную версию str
.
Если some_function был объявлен как:
extern void some_function(const char * s, int l);
Тогда, так как компилятор может видеть, что нет никаких операций, которые изменяют str
в пределах do_it
, он также может обойтись без создания локальной копии str в стеке, даже если str не была объявлена static
.