2016-04-11 2 views
0

Я хочу передать следующее функции в C:Как передать изменчивую переменную функции в c?

#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC)) 

Следующая, кажется, работает достаточно хорошо:

void ZeroRegister(unsigned long * _REG) 
{ 
    #define vReg (*((volatile unsigned long *)_REG)) 
    vReg = 0; 
} 

Есть ли лучший способ кодирования это? Или мой код испорчен? Кроме предупреждения компилятора, он генерирует.

+1

Почему вы использовали '# define' для этого; вы могли бы также написать '* (volatile unsigned long *) _ REG = 0;' –

+2

И какое предупреждение оно генерирует? –

+1

Обратите внимание, что имена, начинающиеся с символа подчеркивания и заглавной буквы, зарезервированы для «реализации» - это означает, что вы не должны использовать такие имена. –

ответ

3

Вы передаёте точно так же, как вы бы передать любую другую переменную, вам просто нужно добавить volatile спецификатор к списку аргументов:

void ZeroRegister(volatile unsigned long * _REG) 
{ 
    *_REG = 0; 
} 

Там нет необходимости пытаться какие-либо трюки препроцессора макросов.

+0

(И тогда, как указал Джонатан Леффлер, имена '_Xnnnn' зарезервированы для реализации). –

4

Вы пишете функцию так, что ожидает указатель на энергонезависимую память, и таким образом вы можете избежать предупреждений (и нет необходимости в дополнительной макрокоманды в функции):

#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC)) 

static void ZeroRegister(volatile unsigned long *REG) 
{ 
    *REG = 0; 
} 

int main(void) 
{ 
    ZeroRegister(&GPIO_PORTF_DATA_R); 
    return 0; 
} 

В Mac OS X 10.11 0,4 с GCC 5.3.0, который компилируется с помощью командной строки, показанной (исходный файл vui.c):

$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \ 
>  -Wold-style-definition -Werror -c vui.c 
$ 

Опуская volatile от параметра функции приводит к предупреждениям (номера строк и имена переменных не соответствуют код выше; они были получены от более ранней версии коды):

… 
vui.c: In function ‘main’: 
vui.c:11:18: error: passing argument 1 of ‘ZeroRegister’ discards ‘volatile’ qualifier from pointer target type [-Werror=discarded-qualifiers] 
    ZeroRegister(&GPIO_PORTF_DATA_R); 
       ^
vui.c:3:6: note: expected ‘long unsigned int *’ but argument is of type ‘volatile long unsigned int *’ 
void ZeroRegister(unsigned long * _REG) 

Обратите внимание, что код компилирования выше избегает имени зарезервирована для реализации. Все имена, начинающиеся с подчеркивания и заглавной буквы (или другого подчеркивания), зарезервированы для реализации. См ISO/IEC 9899: 2011 §7.1.3 Зарезервированные идентификаторы:

  • Все идентификаторы, начинающиеся с подчеркивания и либо прописной буквой или другой подчеркивания всегда зарезервированы для любого использования.
  • Все идентификаторы, начинающиеся с символа подчеркивания, всегда зарезервированы для использования в качестве идентификаторов с областью файлов как в обычном, так и в пространстве имен тегов.
+0

Спасибо, это похоже на отличное решение.Volatile относится к содержимому _REG, а не к его адресу - правильно? static void ZeroRegister (volatile unsigned long * REG) { * REG = 0; } –

+0

Да, этот 'volatile' говорит, что объект, на который указывает объект, является' volatile'. Если указатель сам по себе нестабилен, обозначением будет 'void ZeroRegister (unsigned long * volatile REG)'. Это похоже на 'const'. –

+0

Обратите внимание, что вы используете обратные тики вокруг 'code' в комментариях. –

Смежные вопросы