I need some clarification on the resolution of the very first macro variable in the %put statement.
%let b = 5;
%put ---> &&&&&b.&&b. ==> &&5&b. ===> &55 ;
According to me it should resolved into &55 but i am getting &5555
Completly surprised by this.
Can anyone help me in understanding. I am using the SAS university edition to run this code.
Thanks
Lokesh
I have confirmed from development that this is indeed a bug but due to backward compatiblity it cannot be fixed. Changing how resolution occurs in the example given here could cause problems with existing code:
%let b = 5; %put ---> &&&&&b.&&b. ==> &&5&b. ===> &55 ;
If &55 is the desired result, then the easiest thing to say would be:
%let b =5; %put ---> &&&b&b;
I, too, would have thought that it would resolve to &55
I've cross posted your question to another forum and, unless someone can provide an explanation (other than this being a bug) before I get a response, I'll let you know what I find out.
Art, CEO, AnalystFinder.com
I'm also surprised. Turning on symbolgen doesn't help much:
20 %put ---> &&&&&b.&&b. ; SYMBOLGEN: && resolves to &. SYMBOLGEN: && resolves to &. SYMBOLGEN: Macro variable B resolves to 5 SYMBOLGEN: && resolves to &. SYMBOLGEN: && resolves to &. SYMBOLGEN: Macro variable B resolves to 5 SYMBOLGEN: Macro variable B resolves to 5 ---> &5555
If you take away the trailing dot, which shouldn't be needed, you get a warning about &b55 not resolving:
23 %put ---> &&&&&b.&&b ;
SYMBOLGEN: && resolves to &.
SYMBOLGEN: && resolves to &.
SYMBOLGEN: Macro variable B resolves to 5
SYMBOLGEN: && resolves to &.
SYMBOLGEN: && resolves to &.
SYMBOLGEN: Macro variable B resolves to 5
WARNING: Apparent symbolic reference B55 not resolved.
---> &5&b55
Feels buggish to me. Thanks for posting to SAS-L, @art297
I tested a bit more. Problem only seems to happen when the value of the macro variable is a number.
Below has symbolgen log, with my added annotations.
With a single letter, it looks good to me:
options symbolgen;
%let b=Q;
%put ---> &&&&&b.&&b. ;
10 %put ---> &&&&&b.&&b. ;
First Pass:
SYMBOLGEN: && resolves to &.
SYMBOLGEN: && resolves to &.
SYMBOLGEN: Macro variable B resolves to Q
SYMBOLGEN: && resolves to &.
After first pass, value is &&Q&b.
Second pass:
SYMBOLGEN: && resolves to &.
SYMBOLGEN: Macro variable B resolves to Q
After second pass, value is &QQ
Third pass:
WARNING: Apparent symbolic reference QQ not resolved.
---> &QQ
With a numeric value, it looks bad:
%let b=5;
%put ---> &&&&&b.&&b. ;
12 %put ---> &&&&&b.&&b. ;
First Pass:
SYMBOLGEN: && resolves to &.
SYMBOLGEN: && resolves to &.
SYMBOLGEN: Macro variable B resolves to 5
SYMBOLGEN: && resolves to &.
After first pass, value is &&5&b.;
Second pass:
SYMBOLGEN: && resolves to &.
SYMBOLGEN: Macro variable B resolves to 5
I assume after second pass, value is &55
No idea where this extra &B comes from:
SYMBOLGEN: Macro variable B resolves to 5
No idea where a fourth five comes from:
---> &5555
Seems to only be a problem when value of the macro variable is numeric. Both of the following work as I would expect:
58 options nosymbolgen;
59 %let b=5q;
60 %put ---> &&&&&b.&&b. ;
---> &5q5q
61
62 %let b=q5;
63 %put ---> &&&&&b.&&b. ;
WARNING: Apparent symbolic reference Q5Q5 not resolved.
---> &q5q5
@ChrisHemedinger: I think we need one of the developer's input on this one. Finally, after 43 years of looking, I think this one might actually be a bug.
Art, CEO, AnalystFinder.com
I've alerted some internal SAS macro experts -- hopefully will have a ruling soon!
@Tom pointed out in SAS-L thread that values that look like hexadecimal numbers get doubled:
So:
79 %let b=0A;
80 %put ---> &&&&&b.&&b. ;
---> &0A0A0A0A
But:
82 %let b=0Z;
83 %put ---> &&&&&b.&&b. ;
---> &0Z0Z
So yeah, looks like something funky happening when macro processor sees a 'numeric' value.
Until we get the answer on the buggy behaviour with the test string here is a solution to how to generate the expected value using a modification of the value.
To just get two copies of macro variable B next to each other you just need.
%put &b.&b;
If you don't mind introducing macro quoting then you could just quote the extra &.
%put %str(&)&b.&b;
Or you could double it up.
%put &&&b.&b;
But that will yield different result than the one with macro quoting if the value of &B.&B looks like a valid macro variable name.
I have confirmed from development that this is indeed a bug but due to backward compatiblity it cannot be fixed. Changing how resolution occurs in the example given here could cause problems with existing code:
%let b = 5; %put ---> &&&&&b.&&b. ==> &&5&b. ===> &55 ;
If &55 is the desired result, then the easiest thing to say would be:
%let b =5; %put ---> &&&b&b;
Thanks @russt_sas,
Can you provide any more information about how this bug works? For example, what situations would trigger this bug? What mistake is the word scanner or macro processor making? I recognize this may be asking for a "peak behind the curtain," but sometimes understanding how the macro processor works in these odd scenarios can shed light on other situations. And would be nice to know how to avoid this bug.
Perhaps this is worthy of writing up a TS note to document it?
Thanks again,
--Q.
Quentin,
All I can offer is, it has to do with the macro facility creating a new line of source track that it stacks on top of the old one with each pass. Things work fine when it is characters alone or alphanumeric because in those situations the token is treated differently, but when it is just numbers, the token gets classified as an integer and it follows a different path that has a bug in it.
Thanks,
Russ
Thanks much @russt_sas, for taking the time to respond to posts here, and blog, and (most importanlty) for all you do for the macro langauge!
Thank you so much for the help.
I will try to post some more example where it seems to be a bug.
Thanks again.
Lokesh
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Select SAS Training centers are offering in-person courses. View upcoming courses for: