Резюме
У меня есть несколько исходных файлов C, которые все объявляют индивидуально называемые статическими глобальными переменными. Я понимаю, что статическая глобальная переменная в каждом файле должна быть видна только внутри этого файла и не должна иметь внешнюю привязку, но на самом деле я могу видеть, когда отладка того, что одинаково названные переменные имеют один и тот же адрес памяти.
Похоже, что ключевое слово static
игнорируется, а глобальные переменные обрабатываются как extern
. Почему это?
Пример кода
foo.c:
/* Private variables -----------------------------------*/
static myEnumType myVar = VALUE_A;
/* Exported functions ----------------------------------*/
void someFooFunc(void) {
myVar = VALUE_B;
}
bar.c:
/* Private variables -----------------------------------*/
static myEnumType myVar = VALUE_A;
/* Exported functions ----------------------------------*/
void someBarFunc(void) {
myVar = VALUE_C;
}
baz.c:
/* Private variables -----------------------------------*/
static myEnumType myVar = VALUE_A;
/* Exported functions ----------------------------------*/
void someBazFunc(void) {
myVar = VALUE_D;
}
Отладочные наблюдения
- Установите точки останова на строке
myVar = ...
внутри каждой функции. - Вызовите
someFooFunc
,someBarFunc
иsomeBazFunc
в этом порядке из основного. - Внутри
someFooFunc
myVar
изначально установлено значениеVALUE_A
, после перехода по строке оно установлено наVALUE_B
. - Внутри
someBarFunc
myVar
по какой-то причине сначала устанавливаетсяVALUE_B
перед тем, как перейти на строку, а неVALUE_A
, как я ожидал бы, указав, что компоновщик может объединить отдельные глобальные переменные, основанные на них, идентичное имя. - То же самое относится к
someBazFunc
, когда он вызывается. - Если я использую отладчик для оценки значения
&myVar
, когда на каждой точке останова указывается тот же адрес.
Инструменты и флаги
Инструментальная цепочка: GNU ARM GCC (6.2 2016q4)
Параметры компилятора:
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mlong-calls -O1 -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -Wall -Wextra -g3 -DDEBUG -DTRACE -DOS_USE_TRACE_ITM -DSTM32L476xx -I"../include" -I"../system/include" -I"../system/include/cmsis" -I"../system/include/stm32l4xx" -I"../system/include/cmsis/device" -I"../foo/inc" -std=gnu11 -MMD -MP -MF"foo/src/foo.d" -MT"foo/src/foo.o" -c -o "foo/src/foo.o" "../foo/src/foo.c"
Параметры компоновщика:
arm-none-eabi-g++ -mcpu=cortex-m4 -mthumb -mlong-calls -O1 -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -Wall -Wextra -g3 -T mem.ld -T libs.ld -T sections.ld -nostartfiles -Xlinker --gc-sections -L"../ldscripts" -Wl,-Map,"myProj.map" --specs=nano.specs -o ...