Levi
Levi

Reputation: 1983

Is the declaration of a variable name in a #define directive well defined?

If I had the following code:

#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;
}

Is the declaration of a_variable well defined? On my system, an int named a_variable is declared, but do I have to worry about alternate compilers declaring an int named VAR_NAME?

BTW, the above code outputs the following:

42
42
123
123

EDIT:

Furthermore, if the previous is well-defined, could I do the following?

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

// Declare an int named a_variable
DECL_VAR;

Upvotes: 3

Views: 474

Answers (2)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726479

do I have to worry about alternate compilers declaring an int named VAR_NAME?

No, you do not have to worry about that. Unless someone redefines VAR_NAME to something else, you will consistently get an int named a_variable.

#define directive is processed by preprocessor before the compiler gets to process the code. By the time the compiler "sees" your code, there is no VAR_NAME in there, only a_variable is left in all places where VAR_NAME has been used.

Furthermore, if the previous is well-defined, could I do the following?

#define DECL_VAR int VAR_NAME

Yes, as long as VAR_NAME is defined, this will work as well.

Note: The fact that it is well defined and standard-compliant does not mean that it is necessarily a good idea to use code like that, because cascaded declarations are difficult to read for human readers of your program.

Upvotes: 8

Peter
Peter

Reputation: 36597

Assuming the implementation complies with the standard, the preprocessor will perform text substitution, so every instance of VAR_NAME will be expanded to a_variable.

There are a couple of exceptions (e.g. macros inside string literals are not expanded). But, if you use the macro in places where a variable name would normally be expected, the expansion will work as you expect.

It is also necessary to avoid reserved identifiers (identifiers that the standard reserves for use by the implementation - i.e. the compiler and standard headers). For example, if you pick a name for your macro or for your variable that is reserved (e.g. that starts with an underscore followed by an uppercase letter, such as _VAR_NAME rather than VAR_NAME) then the behaviour is undefined.

EDIT following edit of the original question: Yes, the expansion of DECL_VAR works as you expect.

I would caution you against such things though. Such tricks do not give many benefits, but can make your code harder to understand (after all, few people will know what DECL_VAR; will mean in your code unless they know you are playing with macros). Code that is harder to understand is harder to get right.

Upvotes: 4

Related Questions