Austin Group Defect Tracker

Aardvark Mark III


Viewing Issue Simple Details Jump to Notes ] Issue History ] Print ]
ID Category Severity Type Date Submitted Last Update
0000336 [1003.1(2008)/Issue 7] Shell and Utilities Objection Enhancement Request 2010-10-16 18:13 2013-10-10 16:40
Reporter dwheeler View Status public  
Assigned To ajosey
Priority normal Resolution Reopened  
Status Under Review  
Name David A. Wheeler
Organization
User Reference
Section make
Page Number 2915
Line Number 95801-95808
Interp Status ---
Final Accepted Text
Summary 0000336: Add recursive variable indirection in makefiles
Description Recursive variable indirection in makefiles, such as $(var1$(var2)), is not officially standardized, but is widely supported and useful. For more, see:
http://article.gmane.org/gmane.comp.standards.posix.austin.general/3119 [^]
http://lists.gnu.org/archive/html/automake/2009-04/msg00040 [^]

Eric Blake reports in the first message that "GNU Automake would really like to standardize double variable indirection". Intriguingly, he reports that "all 'make' implementations that I could get hold of *do* accept this construct correctly; that includes IRIX 6.5, AIX 4.3.3, Tru64 4.0D, Solaris 2.6, HP-UX 10.20, NetBSD, FreeBSD, OpenBSD, and of course GNU".

Perhaps even more tellingly, "Also, we tried an alternative implementation
that uses only constructs specified in POSIX, but that turned out to be
*a* *lot* *less* portable in practice."

This construct is useful in the same way that associative arrays are useful in many other languages (e.g., allowing for easy selection between sets of values, such as selecting different file sets for different platforms). It is also very easy to implement, if there is a make implementation that doesn't already support it. Since it *appears* that this construct is *more* portable than those constructs already in POSIX, this construct should be added.

[This part of a set of comments aimed at trying to increase the scope of functionality in *standard* makefiles. I believe the current standard lacks important functionality.]
Desired Action Lines 95801-95802 and 95807-95808 both contain:
"If string1 in a macro expansion contains a macro
expansion, the results are unspecified."
In both cases, replace them with:
"If string1 in a macro expansion contains a macro
expansion, that inner macro expansion is recursively expanded before use."
Tags No tags attached.
Attached Files

- Relationships

-  Notes
(0000630)
nick (manager)
2010-12-02 17:02

Interpretation response
------------------------
The standard clearly states that the results are unspecified, and conforming applications must conform to this.

Rationale:
-------------
All known implementations have implemented the proposed action, and therefore this interpretation is being considered for TC1.

Notes to the Editor (not part of this interpretation):
-------------------------------------------------------
See desired action. If this interpretation is approved without objection, the editor is encouraged to include this action in the next published Technical Corrigendum.
(0000634)
eblake (manager)
2010-12-09 17:01

During the 9 Dec 2010 meeting, the following points were raised:

HP-UX make has a nesting limit of 100, IRIX make has a nesting limit of 1 (that is, IRIX did not support two levels of recursion). IRIX is no longer supported by SGI, so that does not influence the standard, but wording to this effect is needed:

In a macro definition, behavior is unspecified if string2 recursively refers the expansion of string1, or if string2 has more than <X> levels of nested macros requiring expansion.

where <X> needs some rationale and needs to be somewhere between 1 and 100.

Also to be explored is whether all implementations support ${A} and $(A) synonymously (previous testing only focused on nesting via $(A)); and whether nesting via subst1 and subst2 in ${A:subst1=subst2} is universally supported.
(0000671)
dwheeler (reporter)
2011-02-08 20:06

During the 9 Dec 2010 meeting, it was noted that HP-UX has a nesting limit of 100. No other nesting limits have been identified to date in widely-used implementations (there may be one, but I don't know of one, and no one else has identified any other than the now-abandoned IRIX). Thus, I propose adding this text to deal with limited levels of nesting, with a limit based on the largest limit of a currently-supported implementation:

"In a macro definition, behavior is unspecified if string2 recursively refers the expansion of string1, or if string2 has more than 100 levels of nested macros requiring expansion."

The previous note asked for some additional information. It said, "Also to be explored is whether all implementations support ${A} and $(A) synonymously (previous testing only focused on nesting via $(A)); and whether nesting via subst1 and subst2 in ${A:subst1=subst2} is universally supported". I don't know about "all implementations" and "universally supported", but I did test GNU make and FreeBSD's make, and in both cases (1) ${A} is synonymous with $(A), and (2) substitutions work as expected. So I don't think we need to say anything special about this at all. FYI, the test case I used was as follows:
x=y
y=z
oldsuffix=.o
newsuffix=.c
mylist=a.o b.o
whichlist=$(mylist)
all:
    # should print 4 lines of "z":
    @echo ${${x}}
    @echo $($(x))
    @echo ${$(x)}
    @echo $(${x})
    # Check substitution, should print 2 lines of "a.c b.c"
    @echo ${whichlist:${oldsuffix}=${newsuffix}}
    @echo $(whichlist:$(oldsuffix)=$(newsuffix))


Again, this worked on both GNU make and FreeBSD make. That's not all "makes" but it's encouraging.
(0000999)
eblake (manager)
2011-11-01 14:05

An interesting side note: NeXTSTEP 3.3 (now long obsolete) supports nesting
only if the outer and inner macros alternate in bracketing operators (that
is, ${$()} or $(${}) work, but $($()) fails):
https://lists.gnu.org/archive/html/bug-automake/2011-11/msg00000.html [^]
But since NeXTSTEP is no longer actively maintained and is not striving
for POSIX compliance, this should not be used as a reason to block any
proposed solution to this bug report.
(0001021)
dwheeler (reporter)
2011-11-16 18:40

Given the comments above, here is the revised proposal:

Lines 95801-95802 and 95807-95808 both currently contain:
"If string1 in a macro expansion contains a macro
expansion, the results are unspecified."
In both cases, replace them with:
"If string1 in a macro expansion contains a macro
expansion, that inner macro expansion is recursively expanded before use. Systems shall support at least 100 levels of indirection."

Rationale:
This construct is useful in the same way that associative arrays are useful in many other languages (e.g., allowing for easy selection between sets of values, such as selecting different file sets for different platforms). It is also widely implemented.

Regarding the limit of 100, the only system that might strive for future POSIX compliance, and has a limit at all, is HP-UX. Its maximum is 100. There is no particular rationale for a smaller number, and small values could impede portability in complex situations. Therefore, 100 is used here. The NeXTSTEP 3.3 and SGI systems will not meet this new requirement, but both are obsolete and not striving for POSIX compliance anyway.

"100 ought to be enough for anyone." :-).
(0001873)
dwheeler (reporter)
2013-10-10 16:40

Note that this construct can also implement simple portable conditionals for macro/variable values (e.g., see http://gallium.inria.fr/blog/portable-conditionals-in-makefiles/). [^] It can't replace conditionals for all cases, but for some cases it's adequate.

Note that this is in *addition* to its utility in implementing associative arrays, and the fact that most makes *already* do this.

So, that's yet *another* reason to add recursive variable indirection to the standard's specification of make.

- Issue History
Date Modified Username Field Change
2010-10-16 18:13 dwheeler New Issue
2010-10-16 18:13 dwheeler Status New => Under Review
2010-10-16 18:13 dwheeler Assigned To => ajosey
2010-10-16 18:13 dwheeler Name => David A. Wheeler
2010-10-16 18:13 dwheeler Section => make
2010-10-16 18:13 dwheeler Page Number => 2915
2010-10-16 18:13 dwheeler Line Number => 95801-95808
2010-12-02 17:02 nick Note Added: 0000630
2010-12-02 17:11 nick Interp Status => Pending
2010-12-02 17:11 nick Final Accepted Text => See Note: 0000630
2010-12-02 17:11 nick Status Under Review => Interpretation Required
2010-12-02 17:11 nick Resolution Open => Accepted
2010-12-09 17:01 eblake Note Added: 0000634
2010-12-09 17:03 eblake Interp Status Pending => ---
2010-12-09 17:03 eblake Status Interpretation Required => Under Review
2010-12-09 17:03 eblake Resolution Accepted => Reopened
2010-12-09 17:03 eblake Final Accepted Text See Note: 0000630 =>
2011-02-08 20:06 dwheeler Note Added: 0000671
2011-11-01 14:05 eblake Note Added: 0000999
2011-11-16 18:40 dwheeler Note Added: 0001021
2013-10-10 16:40 dwheeler Note Added: 0001873


Mantis 1.1.6[^]
Copyright © 2000 - 2008 Mantis Group
Powered by Mantis Bugtracker