varname-empty.mk revision 1.6
11.6Srillig# $NetBSD: varname-empty.mk,v 1.6 2020/09/24 06:03:44 rillig Exp $
21.1Srillig#
31.1Srillig# Tests for the special variable with the empty name.
41.1Srillig#
51.6Srillig# There is no variable named "" at all, and this fact is used a lot in
61.6Srillig# variable expressions of the form ${:Ufallback}.  These expressions are
71.6Srillig# based on the variable named "" and use the :U modifier to assign a
81.6Srillig# fallback value to the expression (but not to the variable).
91.6Srillig#
101.6Srillig# This form of expressions is used to implement value substitution in the
111.6Srillig# .for loops.  Another use case is in a variable assignment of the form
121.6Srillig# ${:Uvarname}=value, which allows for characters in the variable name that
131.6Srillig# would otherwise be interpreted by the parser, such as whitespace, ':',
141.6Srillig# '=', '$', backslash.
151.6Srillig#
161.6Srillig# The only places where a variable is assigned a value are Var_Set and
171.6Srillig# Var_Append, and these places protect the variable named "" from being
181.6Srillig# defined.  This is different from read-only variables, as that flag can
191.6Srillig# only apply to variables that are defined.
201.6Srillig#
211.1Srillig# This is because it is heavily used in the .for loop expansion,
221.1Srillig# as well as to generate arbitrary strings, as in ${:Ufallback}.
231.1Srillig
241.2Srillig# Until 2020-08-22 it was possible to assign a value to the variable with
251.2Srillig# the empty name, leading to all kinds of unexpected effects.
261.6Srillig#
271.6Srillig# Before 2020-08-22, the simple assignment operator '=' had an off-by-one
281.6Srillig# bug that caused unrelated memory to be read in Parse_DoVar, invoking
291.6Srillig# undefined behavior.
301.3Srillig?=	default
311.4Srillig=	assigned	# undefined behavior until 2020-08-22
321.3Srillig+=	appended
331.3Srillig:=	subst
341.5Srillig!=	echo 'shell-output'
351.1Srillig
361.1Srillig# The .for loop expands the expression ${i} to ${:U1}, ${:U2} and so on.
371.1Srillig# This only works if the variable with the empty name is guaranteed to
381.1Srillig# be undefined.
391.1Srillig.for i in 1 2 3
401.1SrilligNUMBERS+=	${i}
411.1Srillig.endfor
421.1Srillig
431.1Srilligall:
441.5Srillig	@echo out: ${:Ufallback}
451.5Srillig	@echo out: ${NUMBERS}
46