BookmarkSubscribeRSS Feed
ScottBass
Rhodochrosite | Level 12

This is more a rant than expecting a solution.  But comments, likes, or SASWare Ballot entries are more than welcome.

 

I often use an uncalled macro to comment out a block of code containing slash-asterisk comments.

 

However, I sometimes use contractions (unmatched apostrophes) in my SAS comments.  Which work fine in the SAS code itself.

 

Take this code:

 

* It's a sad world where an apostrophe in a comment in an uncalled macro causes a problem ;
data bar;set sashelp.class;run;
data foo;    /* the output dataset is named "foo" */
   set bar;  /* the input dataset is named "bar" */
             /* and if I enclose this code in an uncalled macro I get "fubar" */
run;

Submit that.  It runs as expected.

 

However, say it was a long block of code that I wanted to comment out, and I want the code following it to run.  So I change the code to:

 

%macro comment;

* It's a sad world where an apostrophe in a comment in an uncalled macro causes a problem ;
data bar;set sashelp.class;run;
data foo;    /* the output dataset is named "foo" */
   set bar;  /* the input dataset is named "bar" */
             /* and if I enclose this code in an uncalled macro I get "fubar" */
run;

%mend;

data blah;
   set sashelp.class;
run;

Much anger and gnashing of teeth.  I tried submitting the magic tokens from EG ;*';*";*/;quit;run; but this didn't fix the problem.  The only thing I could think to fix this was restart the server.

 

Now, anyone who has used SAS more than three months (or less if they start using macro early in their SAS journey) has probably run into this and, with some experience, knows the workaround.  Which is "don't do that".

 

But can anyone explain why this design bug (or do we call these "features"?) would be so hard to fix?  Can't the macro processor determine there's an unmatched quote and quote it?  Or wrap all * ; style quotes in some super quoting function so the unmatched quote doesn't cause havoc?

 

Is the code to the macro processor so fragile that it can never be touched and therefore fixed?

 

(In my "real" code, I have a huge program that runs for about 4 hours.  I then need to analyze some outputs in the work library.  I used this technique to block out about 500 lines of code.  Alas, I didn't see that apostrophe, in the comment, in the code that works fine until I wrap it in a macro.  I ran it twice before I deduced the problem.  There's 8 hours I'll never get back.)

 


Please post your question as a self-contained data step in the form of "have" (source) and "want" (desired results).
I won't contribute to your post if I can't cut-and-paste your syntactically correct code into SAS.
23 REPLIES 23
Shmuel
Garnet | Level 18

I have a habit to use /*.....*/ for comments outside of a data step or a proc, while

using *.....; if the line contains sas statements, like in next example:

/* It's a sad world where an apostrophe in a comment in an uncalled macro causes a problem */
data bar;set sashelp.class;run;
data foo;    * the output dataset is named "foo" *;
   set bar;  * the input dataset is named "bar" *;
             * and if I enclose this code in an uncalled macro I get "fubar" *;
run;

then in case I want to marl the whole part it is easy:

/* It's a sad world where an apostrophe in a comment in an uncalled macro causes a problem *   <<<<<
data bar;set sashelp.class;run;
data foo;    * the output dataset is named "foo" *;
   set bar;  * the input dataset is named "bar" *;
             * and if I enclose this code in an uncalled macro I get "fubar" *;
run;
>>>>>>  */     
SASKiwi
PROC Star

@ScottBass  - I wonder if a macro comment behaves better - %* Can it cope with apostrophes better than normal comments? It's a sad world etc;

ScottBass
Rhodochrosite | Level 12

@SASKiwi wrote:

@ScottBass  - I wonder if a macro comment behaves better - %* Can it cope with apostrophes better than normal comments? It's a sad world etc;


Hi @SASKiwi ,

 

Nope...

 

%macro test;
   /* this is a slash-asterisk comment that will not show in MPRINT output */
   %* this is a percent-asterisk comment that will not show in MPRINT output ;
   * this is an asterisk comment that will show in MPRINT output ;
   data one;x=1;run;
%mend; 
options mprint;
%test;

Replace 

%* this is a percent-asterisk comment that will not show in MPRINT output ;

with 

%* this is a percent-asterisk comment that won't show in MPRINT output ;

 

And re-submit. 


Please post your question as a self-contained data step in the form of "have" (source) and "want" (desired results).
I won't contribute to your post if I can't cut-and-paste your syntactically correct code into SAS.
ScottBass
Rhodochrosite | Level 12

@Shmuel wrote:

I have a habit to use /*.....*/ for comments outside of a data step or a proc, while

using *.....; if the line contains sas statements, like in next example:

/* It's a sad world where an apostrophe in a comment in an uncalled macro causes a problem */
data bar;set sashelp.class;run;
data foo;    * the output dataset is named "foo" *;
   set bar;  * the input dataset is named "bar" *;
             * and if I enclose this code in an uncalled macro I get "fubar" *;
run;

then in case I want to marl the whole part it is easy:

/* It's a sad world where an apostrophe in a comment in an uncalled macro causes a problem *   <<<<<
data bar;set sashelp.class;run;
data foo;    * the output dataset is named "foo" *;
   set bar;  * the input dataset is named "bar" *;
             * and if I enclose this code in an uncalled macro I get "fubar" *;
run;
>>>>>>  */     

I have a habit to use * ; comments as much as possible, and /* */ as little as possible.  That way I can use /* */ around the entire block to comment out a block of code.  If that won't work, I use the uncalled macro "trick" to comment out the block of code.

 

/* It's a sad world where an apostrophe in a comment in an uncalled macro causes a problem * <<<<< data bar;set sashelp.class;run; data foo; * the output dataset is named "foo" *; set bar; * the input dataset is named "bar" *; * and if I enclose this code in an uncalled macro I get "fubar" *; run; >>>>>> */

This would be incredibly tedious to comment out a block of code of any size.  Just use an uncalled macro.  Just make sure there are no unbalanced quotation marks.

 


Please post your question as a self-contained data step in the form of "have" (source) and "want" (desired results).
I won't contribute to your post if I can't cut-and-paste your syntactically correct code into SAS.
Amir
PROC Star

I expect you might already be aware of this, but according to the documentation on comments part of the restrictions for the *message; style of comment syntax says:

 

This form of comment cannot be used to hide text from the SAS macro facility.

So your experience does appear to be consistent with the documentation, i.e., the apostrophe "cannot be used to hide text from the SAS macro facility."

 

It then also goes on to give the tip:

 

Tip When using comments within a macro definition or to hide text from the SAS macro facility, use this style comment:
   /* message */

 

HTH.

 

Kind regards,

Amir.

 

Edit: Fixed typo.

Shmuel
Garnet | Level 18

@Amir , as you quoted:

"This form of comment cannot be used to hide text from the SAS macro facility."

Which means - be aware of using & and % in a comment, that is a part of a macro - because 

it should be interpreted as part  of the code.

Anyhow, having a  *message; comment, that does not contain those special characters, will be

interpreted as is and finally sas will ignore it.

ScottBass
Rhodochrosite | Level 12

Which means - be aware of using & and % in a comment, that is a part of a macro - because 

it should be interpreted as part  of the code.

(Emphasis added)

 

Another mini-rant I guess...

 

I sometimes feel that SAS uses "works as documented" as a way to explain away "less than ideal" design.  I've never accepted that.  If in my opinion, the functionality is deficient (at least to me), I'll raise the issue.  Documenting poor behaviour does not make it acceptable behaviour.

 

And in my opinion a comment statement should be able to contain anything, even in a macro.  And I can't see this as a hard problem to fix, just a low ROI fix as I stated previously.

 

But you know what they say about opinions...

 

 


Please post your question as a self-contained data step in the form of "have" (source) and "want" (desired results).
I won't contribute to your post if I can't cut-and-paste your syntactically correct code into SAS.
ScottBass
Rhodochrosite | Level 12

@Amir wrote:

I expect you might already be aware of this, but according to the documentation on comments part of the restrictions for the *message; style of comment syntax says:

 

This form of comment cannot be used to hide text from the SAS macro facility.

So your experience does appear to be consistent with the documentation, i.e., the apostrophe "cannot be used to hide text from the SAS macro facility."

 

It then also goes on to give the tip:

 

Tip When using comments within a macro definition or to hide text from the SAS macro facility, use this style comment:
   /* message */

 

HTH.

 

Kind regards,

Amir.

 

Edit: Fixed typo.


Hi @Amir ,

 

I read that documentation excerpt differently.  I'm not trying to hide anything at all from the macro processor.  Instead, I just want a perfectly legal statement in open code - a * ; style comment statement containing an apostrophe (unbalanced single quote) - to not turn into a fatal error if I enclose that perfectly legal SAS code within a macro.

 

Run this code, and note the difference in the MPRINT output:

 

%macro test;
   /* this is a slash-asterisk comment that will not show in MPRINT output */
   %* this is a percent-asterisk comment that will not show in MPRINT output ;
   * this is an asterisk comment that will show in MPRINT output ;
   data one;x=1;run;
%mend; 
options mprint;
%test;

 

In my "real" SAS macros, I often want to use * ; style comments, if I want the MPRINT output to document what the generated SAS code is doing.

 

Look, I get it...SAS macro is what 30+ years old?  The C code implementing the macro tokenizer probably hasn't been touched in many many years.  The original SAS macro developers may have retired (although SAS does have incredible employee loyalty; who'd want to retire when you've got that cafeteria for all your meals?)  Fixing this design issue would require programmer's time, testing, backwards compatibility, and other issues.  And what is the return on investment to SAS to fix this design issue?  Probably less than nil.  Spend the programmer's time on stuff that will make money.

 

And yeah, in a "real" macro, I would just get angry at the current behaviour, then fix the problem.  But in my original use case (using an uncalled macro to comment out a block of code), the current behaviour is certainly a PITA.

 

Like I said, my original post is more of a rant.  The rant will either get sympathy and perhaps some traction, or die a quick death.  Probably the latter.

 

P.S.:  Since my original post, I've discovered the workaround that saves me from having to restart the workspace server.

 

SAS Log:

 

27         %macro test;
28            /* this is a slash-asterisk comment that will not show in MPRINT output */
29            %* this is a percent-asterisk comment that won't show in MPRINT output ;
30            * this is an asterisk comment that will show in MPRINT output ;
31            data one;x=1;run;
32         %mend;
33         options mprint;
34         %test;
35         
36         
37         GOPTIONS NOACCESSIBLE;
38         %LET _CLIENTTASKLABEL=;
39         %LET _CLIENTPROCESSFLOWNAME=;
40         %LET _CLIENTPROJECTPATH=;
41         %LET _CLIENTPROJECTPATHHOST=;
NOTE: The quoted string currently being processed has become more than 262 characters long.  You might have unbalanced 
      quotation marks.
42         %LET _CLIENTPROJECTNAME=;
43         %LET _SASPROGRAMFILE=;
44         %LET _SASPROGRAMFILEHOST=;

 

So the problem is that a "quoted string" starts with the apostrophe, and the log message kicks in at 262 characters.  So what's happened is I started creating a macro, but the macro thinks it contains a long unterminated string, which includes the %mend statement.

 

So now submit:

 

%mend;
;*';*";*/;quit;run;  <<<<< this is optional but does not hurt

Keep submitting until you get this error:

ERROR: No matching %MACRO statement for this %MEND statement.

You should now have your workspace server back again.

 

(Now I've provided R&D even less reason to fix this annoying behaviour 😉 )


Please post your question as a self-contained data step in the form of "have" (source) and "want" (desired results).
I won't contribute to your post if I can't cut-and-paste your syntactically correct code into SAS.
Amir
PROC Star

@ScottBass reading all of your replies so far gives more context and I expect you're right about this behaviour not changing any time soon.

 

I know from the outset you said you weren't expecting a solution, but as an alternative to using a macro definition to comment out some code, you might want to consider datalines4 (obviously only if your code doesn't have four semicolons in a row), e.g. your original code would become:

 

data _null_;
   datalines4;
* It's a sad world where an apostrophe in a comment in an uncalled macro causes a problem ;
data bar;set sashelp.class;run;
data foo;    /* the output dataset is named "foo" */
   set bar;  /* the input dataset is named "bar" */
             /* and if I enclose this code in an uncalled macro I get "fubar" */
run;
;;;;

And as for your "real" macros, if you're having to make the effort to "fix the problem" then a not-pretty preemptive effort could be made by adding a space-apostrophe-space ( ' ) after your original apostrophe, e.g., your example would become:

 

%macro comment;

* It' ' s a sad world where an apostrophe in a comment in an uncalled macro causes a problem ;
data bar;set sashelp.class;run;
data foo;    /* the output dataset is named "foo" */
   set bar;  /* the input dataset is named "bar" */
             /* and if I enclose this code in an uncalled macro I get "fubar" */
run;

%mend;

data blah;
   set sashelp.class;
run;

And lastly, maybe just don't use contractions! 😉 Although, the more observant amongst you will note I've used at least one in every sentence in this post! Question is, was that planned or wasn't it? 🤔

 

 

Kind regards,

Amir.

ScottBass
Rhodochrosite | Level 12

@Amir wrote:

@ScottBass reading all of your replies so far gives more context and I expect you're right about this behaviour not changing any time soon.

 

SB: This isn't the only SAS idiosyncrasy I don't expect a change to any time soon...

 

I know from the outset you said you weren't expecting a solution, but as an alternative to using a macro definition to comment out some code, you might want to consider datalines4 (obviously only if your code doesn't have four semicolons in a row), e.g. your original code would become:

 

data _null_;
   datalines4;
* It's a sad world where an apostrophe in a comment in an uncalled macro causes a problem ;
data bar;set sashelp.class;run;
data foo;    /* the output dataset is named "foo" */
   set bar;  /* the input dataset is named "bar" */
             /* and if I enclose this code in an uncalled macro I get "fubar" */
run;
;;;;

 

SB: Thanks, I wouldn't have thought of datalines4.  I can have a play with that.

 

And as for your "real" macros, if you're having to make the effort to "fix the problem" then a not-pretty preemptive effort could be made by adding a space-apostrophe-space ( ' ) after your original apostrophe, e.g., your example would become:

 

%macro comment;

* It' ' s a sad world where an apostrophe in a comment in an uncalled macro causes a problem ;
data bar;set sashelp.class;run;
data foo;    /* the output dataset is named "foo" */
   set bar;  /* the input dataset is named "bar" */
             /* and if I enclose this code in an uncalled macro I get "fubar" */
run;

%mend;

data blah;
   set sashelp.class;
run;

 

SB: Nah, I just change "it's" to "it is", "don't" to "do not", etc.  I suspect "it%'s" would also work in the MPRINT output, but I've never tried that.

 

And lastly, maybe just don't use contractions! 😉 Although, the more observant amongst you will note I've used at least one in every sentence in this post! Question is, was that planned or wasn't it? 🤔

 

SB: Or just don't comment code.  That too is a "solution" 😉

 

Kind regards,

Amir.


 


Please post your question as a self-contained data step in the form of "have" (source) and "want" (desired results).
I won't contribute to your post if I can't cut-and-paste your syntactically correct code into SAS.
Amir
PROC Star

@ScottBass Yes your "solution" reminds me of a colleague's suggestion in the lead up to Y2K, which was to delete all data & code which would remove the bug!

 

I wanted (but forgot) to, mention that depending upon your interface, another advantage of using datalines4 would be that the code that is "commented out" would be highlighted and so will stand out to you or another reader who might otherwise miss the fact it is not in use, and the highlighting would serve as a useful reminder to "uncomment" the code later, assuming it was a temporary measure.

 

 

Kind regards,

Amir.

ballardw
Super User

Roughly 25 years ago when I started self-learning use of the macro facility I ran into that behavior with comments.

 

I haven't used any form of comment except the /* */ since then because of the documentation. That way I don't have to "change" from * ; to %* ; commenting.

The SAS enhanced editor has made it extremely easy to do so: highlight code then CTRL /

You don't want to nest comments inside comments either.

 

I was running some modeling that ran for 4+ DAYS, so I can well understand frustration when something, like the output wasn't designed to create as much output and had fields overwriting each other requiring modification to output statements and then rerunning the code for 4 more days...

ghosh
Barite | Level 11

My approach for commenting a section of code is:

%if 0 %then %do;
* It's a sad world where an apostrophe in a comment in an uncalled macro causes a problem ;
data bar;set sashelp.class;run;
data foo;    /* the output dataset is named "foo" */
   set bar;  /* the input dataset is named "bar" */
             /* and if I enclose this code in an uncalled macro I get "fubar" */
run;
%end;

Then, if you need to execute the commented coded, just change the first line to :

%if 1 %then %do;

SAS Innovate 2025: Call for Content

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!

Submit your idea!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 23 replies
  • 2796 views
  • 18 likes
  • 10 in conversation