Rule 19.12 (# and ## operator) real issue?

6.19 Preprocessing Directives

Moderators: misra-c, david ward

Post Reply
rmgalles
Posts: 7
Joined: Fri Jan 20, 2006 3:45 pm
Location: USA

Rule 19.12 (# and ## operator) real issue?

Post by rmgalles » Mon Feb 06, 2006 10:16 pm

I recognize that \"The order in which # and ## operations are evaluated during macro substitution (6.10.3.2, 6.10.3.3).\" [ISO C 9899:1999 J.1 Unspecified behavior] is UNSPECIFIED behavior.

However, what is the real issue with the order of evaluation being unspecified? I realize that rule 19.13 goes even further than MISRA-C:1998 and advises that these operators not even be used at all. However, I'm wondering if someone can provide an example where the order of evaluation matters?

The only example I can think of is:

Code: Select all

#define MYMACRO(a,b) # a ## b
MYMACRO(foo,bar)
Could produce (## evaluated first, then #):

Code: Select all

\"foobar\"
or (# evaluated first, then ##):

Code: Select all

\"foo\" bar
depending on the order of evaluation.

However, as long as ONLY # operators, or ONLY ## operators are used (i.e., # and ## operators are not BOTH used in the SAME macro), then I don't see a problem.

It is sometimes useful to use these operators more than once within a macro, particularly the ## operator:

Code: Select all

#define MY_IDENTIFIER(a) PRE_##a##_SUF
MY_IDENTIFIER(foo)
Will always result in a new identifier:

Code: Select all

PRE_foo_SUF
It doesn't matter which ## operator executes first:

Code: Select all

PRE_##foo##_SUF -> PRE_foo##_SUF -> PRE_foo_SUF
PRE_##foo##_SUF -> PRE_##foo_SUF -> PRE_foo_SUF
Both result in the proper final identifier.

Macros can then be used to replace otherwise \"copy-and-paste\" code with a single macro. Then, changes to the repetitive code can be made in a single location (the macro) rather than duplicated across several lines of code. This minimizes \"copy-and-paste\" errors in the original code creation, as well as \"copy-and-paste\" errors in code maintenance.

Granted, the use of such macros is not extremely common or widespread. However, it does have its practical uses, and when done may require more than one ## operator within a single macro.

I just wondered if a specific example is available that shows where the order of evaluation matters or could cause a problem based on the UNSPECIFIED behavior when only one TYPE of operator (# only, or ## only) is used in a macro, but the one operator may be used MORE THAN ONCE in the same macro.

If there is no such issue, could rule 19.12 be updated to:
\"Both # and ## operators shall not be used in the same macro definition.\"

misra-c
Posts: 572
Joined: Thu Jan 05, 2006 1:11 pm

Post by misra-c » Thu Apr 27, 2006 11:59 am

The standard allows and experience has shown that this behaviour can vary between compilers, and within the same compiler dependent on context.

Your example shows that the result can depend of the order of evaluation which is unspecifed.
---
Posted by and on behalf of
the MISRA C Working Group

rmgalles
Posts: 7
Joined: Fri Jan 20, 2006 3:45 pm
Location: USA

Post by rmgalles » Thu Apr 27, 2006 3:29 pm

I agree with the statement:
result can depend o[n] the order of evaluation which is unspecifed
... when both the # and the ## operator are in the same macro. However, can someone provide an example when only one of the operators (only #, or only ##) are used more than once in a single macro definition?

My recommendation is to use the following wording:
Rule 19.12 (req): The # and ## operators shall not be used together in the same macro definition.
Can someone comment on why the original wording would be preferred to this alternative? My second example doesn't have any issues with operator evaluation order that I can identify, yet it violates the original wording. With the updated wording, it would be okay, while the first example is still a violation -- as it should be, since it does have an issue with order of evaluation.

misra-c
Posts: 572
Joined: Thu Jan 05, 2006 1:11 pm

Re: Rule 19.12 (# and ## operator) real issue?

Post by misra-c » Thu Mar 12, 2009 10:59 am

If the macro

Code: Select all

#define m (a,b) a##3##b
is invoked as

Code: Select all

m ( PRE, SUF ) = 0;
then the order of evaluation is important. The result of the ## operator
must be a valid preprocessing token.

Left-to-right evaluation gives 'PRE3' followed by 'PRE3SUF'.

However, the first expansion from right-to-left evaluation is 3SUF, which is
not a valid preprocessing token.
---
Posted by and on behalf of
the MISRA C Working Group

dcrocker
Posts: 7
Joined: Fri Oct 07, 2005 7:46 pm
Company: Escher Technologies Ltd.
Location: Ash Vale, Surrey, UK
Contact:

Re: Rule 19.12 (# and ## operator) real issue?

Post by dcrocker » Wed Mar 23, 2011 8:37 pm

According to my reading of the standard, 3SUF is indeed a valid preprocessing token - it is a pp-number.
David Crocker
Escher Technologies Ltd.
http://www.eschertech.com

misra-c
Posts: 572
Joined: Thu Jan 05, 2006 1:11 pm

Re: Rule 19.12 (# and ## operator) real issue?

Post by misra-c » Thu Mar 31, 2011 4:10 pm

Apologies, 3SUF is indeed a pp-number and therefore a valid preprocessing token. A correct example would have been

Code: Select all

#define m (a,b) a##.##b 
as this would have resulted in .SUF which is not a single preprocessing token but the two tokens . and SUF respectively.
---
Posted by and on behalf of
the MISRA C Working Group

misra-c
Posts: 572
Joined: Thu Jan 05, 2006 1:11 pm

Re: Rule 19.12 (# and ## operator) real issue?

Post by misra-c » Fri Apr 01, 2011 9:13 am

The previous response gives two preprocessing tokens regardless of order of evaluation of ## operators.

A better example would be:

Code: Select all

#define m(a,b) a##.##b

m(1,e30)
which is defined on a left-to-right evaluation but undefined on right-to-left because .e30 is two preprocessing tokens.
---
Posted by and on behalf of
the MISRA C Working Group

Post Reply

Return to “6.19 Preprocessing Directives”