How to: Use the #globaldefine Directive to Avoid Overwriting
Applies To: Microsoft Dynamics AX 2012 R3, Microsoft Dynamics AX 2012 R2, Microsoft Dynamics AX 2012 Feature Pack, Microsoft Dynamics AX 2012
The #globaldefine directive is similar to the #define directive. The difference is that #define directives generally take precedence over #globalmacro directives. This is true regardless of which directive occurs first in the X++ code.
A #globaldefine never overwrites a #define directive that has both a macro name and a value. A #globaldefine can overwrite another #globaldefine.
A #define directive that has only a name does not overwrite a #globalmacro that has both a name and a value.
Tip
It is recommended that you use #define, and that you do not use #globaldefine. Use of #globaldefine can create uncertainty that makes code difficult to maintain.
Prerequisites
For this topic, you must understand the information in How to: Test a Macro Value.
Code Sample for #globaldefine
The following code sample shows a difference in the behavior of #define and #globaldefine. Following the code sample is a table explaining the conclusions from the output. The primary test case in the code sample is labeled 12.
static void InteractDefineGlobalJob(Args _args)
{
;
// Pairs of #define - #globaldefine directives (same macro names).
#define.11_DEFINEvalue_GLOBALnoval("11__DEFINE.")
#globaldefine.11_DEFINEvalue_GLOBALnoval
#define.12_DEFINEnoval_GLOBALvalue
#globaldefine.12_DEFINEnoval_GLOBALvalue("12_GLOBAL.")
#define.13_DEFINEvalue_GLOBALvalue("13__DEFINE.")
#globaldefine.13_DEFINEvalue_GLOBALvalue("13_GLOBAL.")
// Pairs of #globaldefine - #define directives.
#globaldefine.27_GLOBALvalue_DEFINEnoval("27_GLOBAL.")
#define.27_GLOBALvalue_DEFINEnoval
#globaldefine.28_GLOBALnoval_DEFINEvalue
#define.28_GLOBALnoval_DEFINEvalue("28__DEFINE.")
#globaldefine.29_GLOBALvalue_DEFINEvalue("29_GLOBAL.")
#define.29_GLOBALvalue_DEFINEvalue("29__DEFINE.")
// Pairs of same directive types.
#define.50_DEFINEvalue_DEFINEnoval("50__DEFINE 1.")
#define.50_DEFINEvalue_DEFINEnoval
#globaldefine.64_GLOBALvalue_GLOBALnoval("64_GLOBAL 1.")
#globaldefine.64_GLOBALvalue_GLOBALnoval
#globaldefine.65_GLOBALnoval_GLOBALvalue
#globaldefine.65_GLOBALnoval_GLOBALvalue("65_GLOBAL 2.")
#globaldefine.66_GLOBALvalue_GLOBALvalue("66_GLOBAL 1.")
#globaldefine.66_GLOBALvalue_GLOBALvalue("66_GLOBAL 2.")
// Infolog outputs.
info(#11_DEFINEvalue_GLOBALnoval);
info(#12_DEFINEnoval_GLOBALvalue);
info(#13_DEFINEvalue_GLOBALvalue);
info(#27_GLOBALvalue_DEFINEnoval);
info(#28_GLOBALnoval_DEFINEvalue);
info(#29_GLOBALvalue_DEFINEvalue);
info(#50_DEFINEvalue_DEFINEnoval);
info(#64_GLOBALvalue_GLOBALnoval);
info(#65_GLOBALnoval_GLOBALvalue);
info(#66_GLOBALvalue_GLOBALvalue);
/***************************** Actual Infolog output
Message (09:31:26 pm)
11__DEFINE.
12_GLOBAL.
13__DEFINE.
27_GLOBAL.
28__DEFINE.
29__DEFINE.
50__DEFINE 1.
64_GLOBAL 1.
65_GLOBAL 2.
66_GLOBAL 2.
*****************************/
}
Explanation of Outputs and Conclusions
The following table explains the test case outcomes from the previous code sample. The explanations document the behavior of #globalmacro.
Test case |
Explanation |
---|---|
13 and 29 |
Shows that #define usually takes precedence over #globaldefine, regardless of which directive occurs first in the X++ code. Test case 12 shows this is not always true. |
12 |
Shows that #globaldefine overwrites #define when #globaldefine is giving a value to an existing macro that has no value. Test cases 13 and 29 are more common and realistic. |
50 and 64 |
Shows that a #globaldefine that has a name but no value does not overwrite a #globaldefine that has both a name and a value. The same is true between a pair of #define directives. This resembles test case 12. |
65 and 66 |
Shows that a #globaldefine that has both a name and a value overwrites a previous #globaldefine. |
Different from #if Test Approach
The exact semantics of #globaldefine cannot be achieved through #if test directives. By using #if tests you can avoid overwriting a #define and a #globaldefine. But #if tests cannot distinguish between #define and #globaldefine macros.
The following code sample is the closest you can come to achieving the #globaldefine semantic with other directives such as #if.
static void IfNotDefineNestGlobalJob (Args _args)
{
;
#undef.MaybeMac
#ifnot.MaybeMac
#define.MaybeMac(4444) // Works.
#endif
#if.MaybeMac
info(int2str(#MaybeMac));
#endif
/********************** Actual Infolog output
Message (07:43:32 pm)
4444
**********************/
}
See also
Announcements: New book: "Inside Microsoft Dynamics AX 2012 R3" now available. Get your copy at the MS Press Store.