behavior of define

  • Thread starter Mohammad Omer Nasir
  • Start date
M

Mohammad Omer Nasir

I was read Linux kernel code [linux-2.6.19] in which I saw few define
macro defines in functions. The snap of the function is following and
file name "err_ev6.c".

static int
ev6_parse_cbox(u64 c_addr, u64 c1_syn, u64 c2_syn,
u64 c_stat, u64 c_sts, int print)
{
char *sourcename[] = { "UNKNOWN", "UNKNOWN", "UNKNOWN",
"MEMORY", "BCACHE", "DCACHE",
"BCACHE PROBE", "BCACHE PROBE" };
char *streamname[] = { "D", "I" };
char *bitsname[] = { "SINGLE", "DOUBLE" };
int status = MCHK_DISPOSITION_REPORT;
int source = -1, stream = -1, bits = -1;

#define EV6__C_STAT__BC_PERR (0x01)
#define EV6__C_STAT__DC_PERR (0x02)
#define EV6__C_STAT__DSTREAM_MEM_ERR (0x03)
#define EV6__C_STAT__DSTREAM_BC_ERR (0x04)
..
..
..
}

I was tested following code.

#define AAA 90

void fun( )
{
#define _AAA 100
}

int main()
{
printf( "%d %d", AAA, _AAA );
return 0;
}

The result was "90 100". I am not able to understand, what is the
difference in use of define macro to defines in Global scoop or with in
Function scoop?

Regards,

-aims
 
O

Ondra Holub

Mohammad Omer Nasir napsal:
I was read Linux kernel code [linux-2.6.19] in which I saw few define
macro defines in functions. The snap of the function is following and
file name "err_ev6.c".

static int
ev6_parse_cbox(u64 c_addr, u64 c1_syn, u64 c2_syn,
u64 c_stat, u64 c_sts, int print)
{
char *sourcename[] = { "UNKNOWN", "UNKNOWN", "UNKNOWN",
"MEMORY", "BCACHE", "DCACHE",
"BCACHE PROBE", "BCACHE PROBE" };
char *streamname[] = { "D", "I" };
char *bitsname[] = { "SINGLE", "DOUBLE" };
int status = MCHK_DISPOSITION_REPORT;
int source = -1, stream = -1, bits = -1;

#define EV6__C_STAT__BC_PERR (0x01)
#define EV6__C_STAT__DC_PERR (0x02)
#define EV6__C_STAT__DSTREAM_MEM_ERR (0x03)
#define EV6__C_STAT__DSTREAM_BC_ERR (0x04)
.
.
.
}

I was tested following code.

#define AAA 90

void fun( )
{
#define _AAA 100
}

int main()
{
printf( "%d %d", AAA, _AAA );
return 0;
}

The result was "90 100". I am not able to understand, what is the
difference in use of define macro to defines in Global scoop or with in
Function scoop?

Regards,

-aims

It does not matter, where you #define your macro. When something is
defined inside of function, it is usually #undefined in the same
function (I do not know, ehther it is in your case too), because such
macro is meant only for usage in this function.
 
G

Gavin Deane

Mohammad said:
I was read Linux kernel code [linux-2.6.19] in which I saw few define
macro defines in functions. The snap of the function is following and
file name "err_ev6.c".

static int
ev6_parse_cbox(u64 c_addr, u64 c1_syn, u64 c2_syn,
u64 c_stat, u64 c_sts, int print)
{

#define EV6__C_STAT__BC_PERR (0x01)

}

I was tested following code.

#define AAA 90

void fun( )
{
#define _AAA 100
}

int main()
{
printf( "%d %d", AAA, _AAA );
return 0;
}

The result was "90 100". I am not able to understand, what is the
difference in use of define macro to defines in Global scoop or with in
Function scoop?

You mean scope, not scoop.

What is the difference? Nothing at all. Macro substitution (in your
case, replacing all[*] occurances of AAA with 90 and all[*] occurances
of _AAA with 100) is done as a simple textual replacement by the
preprocessor before the compiler gets to see the code.

[*] When I say all, I really mean all occurances of the symbol that
appear *after* the #define.

The preprocessor knows nothing about C++ scope rules. After it
encounters #define AAA 90, it will blindly replace all subsequent
occurances of AAA with 90, regardless of (amongst other things) the
scope of the #define or the symbol.

I'm only guessing, but one possible reason for the style of the code
you found is that, if the macro EV6__C_STAT__BC_PERR is only intended
to be used within the ev6_parse_cbox function, the author may have put
the macro definition inside the function to document that intent to a
human reader. But the preprocessor doesn't know that and, as you have
found, it will replace all subsequent occurances of
EV6__C_STAT__BC_PERR with (0x01) whether they are inside the definition
of ev6_parse_cbox or not.

Two things to note from a C++ point of view:
1. In C++, their is no reason to use a macro for a simple constant like
this. Use const int instead. Then the compiler will be able to respect
all the C++ rules (e.g. scope, type) that the preprocessor knows
nothing about.
2. Don't use names with a double underscore in your own code. They are
reserved for the implementation.

Gavin Deane
 
R

Ron Natalie

Mohammad said:
{
#define _AAA 100
}
UNDEFINED. Underscore followed by uppercase letter is reserved
to the implementation.
int main()
{
printf( "%d %d", AAA, _AAA );
return 0;
}

The result was "90 100". I am not able to understand, what is the
difference in use of define macro to defines in Global scoop or with in
Function scoop?
#define has no scope. It's a text substitution that occurs early
on in the program compilation.

const variables, enums, etc... have scope and should be preferred.
 
M

Mohammad Omer Nasir

Thanks, now all of the points are clear..

regards,

-aims

Mohammad said:
I was read Linux kernel code [linux-2.6.19] in which I saw few define
macro defines in functions. The snap of the function is following and
file name "err_ev6.c".
static int
ev6_parse_cbox(u64 c_addr, u64 c1_syn, u64 c2_syn,
u64 c_stat, u64 c_sts, int print)
{<snip>
#define EV6__C_STAT__BC_PERR (0x01)<snip>



I was tested following code.
#define AAA 90
void fun( )
{
#define _AAA 100
}
int main()
{
printf( "%d %d", AAA, _AAA );
return 0;
}
The result was "90 100". I am not able to understand, what is the
difference in use of define macro to defines in Global scoop or with in
Function scoop?You mean scope, not scoop.

What is the difference? Nothing at all. Macro substitution (in your
case, replacing all[*] occurances of AAA with 90 and all[*] occurances
of _AAA with 100) is done as a simple textual replacement by the
preprocessor before the compiler gets to see the code.

[*] When I say all, I really mean all occurances of the symbol that
appear *after* the #define.

The preprocessor knows nothing about C++ scope rules. After it
encounters #define AAA 90, it will blindly replace all subsequent
occurances of AAA with 90, regardless of (amongst other things) the
scope of the #define or the symbol.

I'm only guessing, but one possible reason for the style of the code
you found is that, if the macro EV6__C_STAT__BC_PERR is only intended
to be used within the ev6_parse_cbox function, the author may have put
the macro definition inside the function to document that intent to a
human reader. But the preprocessor doesn't know that and, as you have
found, it will replace all subsequent occurances of
EV6__C_STAT__BC_PERR with (0x01) whether they are inside the definition
of ev6_parse_cbox or not.

Two things to note from a C++ point of view:
1. In C++, their is no reason to use a macro for a simple constant like
this. Use const int instead. Then the compiler will be able to respect
all the C++ rules (e.g. scope, type) that the preprocessor knows
nothing about.
2. Don't use names with a double underscore in your own code. They are
reserved for the implementation.

Gavin Deane
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top