Доступ к глобальной переменной дает нежелательные значения
Я пытался напечатать переменные через UART со следующим кодом на C.
Процессор - Intel 80486
Компилятор - IC компилятор (от Intel, выпущенный в 1990 году)
uint32_t unGlobal = 0xABCDEF90;
void main (void)
{
uint32_t unLocal = 0x12345678;
UartWrite (unLocal);
UartWrite (unGlobal);
}
UartWrite () - драйвер последовательного порта. Аргумент UartWrite является 32-битным, и внутри он печатает каждый символ.
Здесь локальная переменная печатается правильно, но печать глобальной переменной дает ненужные значения! В чем может быть причина не получить значение глобальной переменной. Может кто-то помочь мне с этим?
3 ответа
Проблема была со статической инициализацией. Потому что повторная инициализация глобальной переменной во время выполнения дает правильное значение. Спасибо, рэйкер, @Lundin и все
Тип аргумента в прототипе для UartWrite может быть недостаточного размера, чтобы содержать значение для вашей глобальной переменной. У меня нет прототипа, но для похожих функций (без сомнения, для разных библиотек) тип аргумента char
, Если это также char
в вашем прототипе, а затем передать значение для unsigned int
будет вероятным источником вашей проблемы.
Следующее иллюстрирует сценарий, в котором функция будет принимать переменную размера, слишком большую для прототипа, без ошибок, но затем может дать неожиданные результаты:
int func(char a)
{
a = 10000;
return a;
}
int main(void)
{
int a = 10000;
int b;
b = func(a);// note int type, or 10000 does not fit into a char type
// b is returned, but not with the expected value.
printf("%d" b);
return 0;
}
результаты: b = -24
Опубликовать прототип для UartWrite (??? )
;
РЕДАКТИРОВАТЬ (новая информация)
Я нашел этот документ Intel на компиляторе, выпущенном в 1990 году, который может быть родственником того компилятора, который вы используете. Посмотрите на разделы, начиная со страницы 68:
Каждое глобальное определение символа или ссылка в модуле компиляции имеет атрибут видимости, который управляет тем, как (или если) на него можно ссылаться извне компонента, в котором он определен. Существует пять возможных значений видимости:
• EXTERNAL - компилятор должен обрабатывать символ, как если бы он был определен в другом компоненте. Для определения это означает, что компилятор должен предполагать, что символ будет переопределен (прерван) определением того же имени в другом компоненте. См. Преобразование символа. Если символ функции 69 имеет внешнюю видимость, компилятор знает, что он должен вызываться косвенно, и может встроить заглушку косвенного вызова.
• ПО УМОЛЧАНИЮ - другие компоненты могут ссылаться на символ. Кроме того, определение символа может быть переопределено (прервано) определением того же имени в другом компоненте.
• ЗАЩИЩЕНО - другие компоненты могут ссылаться на символ, но он не может быть заменен определением того же имени в другом компоненте.
• HIDDEN - другие компоненты не могут напрямую ссылаться на символ. Однако его адрес может передаваться другим компонентам косвенно (например, в качестве аргумента вызова функции в другом компоненте или путем сохранения его адреса в ссылке на элемент данных функцией в другом компоненте).
• ВНУТРЕННИЙ - на символ нельзя ссылаться вне его определяющего компонента, ни прямо, ни косвенно.
Чуть дальше вниз Например:
int i __attribute__ ((visibility("default")));
void __attribute__ ((visibility("hidden"))) x () {...}
extern void y() __attribute__ ((visibilty("protected");
Там намного больше. Надеюсь это поможет.
Ключевое слово volatile указывает на то, что "значение может изменяться между различными доступами, даже если оно не изменяется". Попробуйте это и посмотрите, работает ли это для вас.