2015-06-06 1 views
3

Если бы я имел следующий код:Является ли объявление переменной имени в директиве #define четко определенной?

#include <stdio.h> 
#define VAR_NAME a_variable 

int VAR_NAME = 42; 

int main() 
{ 
    printf("%i\n", VAR_NAME); 
    printf("%i\n", a_variable); 
    a_variable = 123; 
    printf("%i\n", VAR_NAME); 
    printf("%i\n", a_variable); 

    return 0; 
} 

хорошо определена декларация a_variable? В моей системе объявлен номер int, названный a_variable, но мне нужно беспокоиться об альтернативных компиляторах, объявляющих int с именем VAR_NAME?

Кстати, приведенный выше код выводит следующее:

42 
42 
123 
123 

РЕДАКТИРОВАТЬ:

Кроме того, если предыдущее определение корректно, я мог сделать следующее?

#define VAR_NAME a_variable 
... 
#define DECL_VAR int VAR_NAME 

// Declare an int named a_variable 
DECL_VAR; 

ответ

8

я должен беспокоиться об альтернативных компиляторов объявляя int имени VAR_NAME?

Нет, вам не о чем беспокоиться. Если кто-то не переопределит VAR_NAME на что-то еще, вы будете последовательно получать int по имени a_variable.

#define директива обрабатывается препроцессором до того, как компилятор доработает код. К тому времени, когда компилятор «видит» ваш код, там нет VAR_NAME, только a_variable остается во всех местах, где используется VAR_NAME.

Кроме того, если предыдущее четко определено, могу ли я сделать следующее?

#define DECL_VAR int VAR_NAME 

Да, до тех пор, как VAR_NAME определено, что это будет работать так же.

Примечание: Тот факт, что она определена и со стандартами, не означает, что это всегда хорошая идея использовать такой код, потому что каскадные заявления трудно читать для человека читателей вашей программы.

4

Предполагая, что выполнение соответствует стандарту, препроцессор выполнит замену текста, поэтому каждый экземпляр VAR_NAME будет расширен до a_variable.

Существует несколько исключений (например, макросы внутри строковых литералов не расширены). Но если вы используете макрос в тех местах, где обычно ожидается имя переменной, расширение будет работать так, как вы ожидаете.

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

EDIT после редактирования исходного вопроса: Да, расширение DECL_VAR работает так, как вы ожидаете.

Я бы предупредил вас об этом. Такие трюки не приносят много преимуществ, но могут сделать ваш код сложнее понять (ведь мало кто знает, что будет означать в вашем коде, если они не знают, что вы играете с макросами). Кодекс, который сложнее понять, сложнее добиться.

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

  • Нет связанных вопросов^_^