EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

How to Auto-generate Unique Labels in C?

Started by aekalman November 23, 2004
Hi All.

This is more of a C-centric, rather than MSP430-specific question, but
with all the compiler vendors here on-line :) I though I'd ask ... I
think I once saw this done, but I've searched everywhere and can't
find it.

Is there a way / what is the best way to have the compiler
auto-generate lables in C code?

In the broadest sense, what I want is to be able to invoke a macro and
have it create a unique label each time it is invoked, e.g.

#define MyUniqueLabelMacro()      // your wizard code here

and use it like this:

{
  ...
  MyUniqueLabelMacro()
  ...
  MyUniqueLabelMacro()
}

so that it results in

{
  ...
  auniquelabel:
  ...
  anotheruniquelabel:
}

I can do this manually by explicitly passing a label name to the
macro, but I would prefer (because the labels are only used locally,
not outside the scope of any function) to not have to pass an argument
to the macro. Each such label must be unique, however, otherwise (in
my experience) many assemblers will choke.

I'd like to see a solution in ANSI C only (no in-line assembly, etc.),
but I'll settle for the latter of the former isn't possible.

I was thinking about something along the lines of using __FILE__ and
__LINE__, but the filename is likely to cause problems with its '.'
character, etc. ...

Thanks for any help.

--Andrew E Kalman, Ph.D.
aek at pumpkin inc dot com

  




Beginning Microcontrollers with the MSP430

Hi Andrew:

#define DoLabel(X) X
#define MyUniqueLabelMacro() A##DoLabel(__LINE__) 

This generates identifiers of the type A<linenumber.  This is a use-once
macro, you can use it exactly once to define a label but can't use it to
reference a label.  If the labels are only inside compounds, then they
are scoped by the compiler so there are no name clashes possible anyway.

--
Paul Curtis, Rowley Associates Ltd  http://www.rowley.co.uk
CrossWorks for MSP430, ARM, and (soon) Atmel AVR processors  

> -----Original Message-----
> From: aekalman [mailto:aek@aek@...] 
> Sent: 23 November 2004 22:28
> To: msp430@msp4...
> Subject: [msp430] How to Auto-generate Unique Labels in C?
> 
> 
> 
> Hi All.
> 
> This is more of a C-centric, rather than MSP430-specific 
> question, but with all the compiler vendors here on-line :) I 
> though I'd ask ... I think I once saw this done, but I've 
> searched everywhere and can't find it.
> 
> Is there a way / what is the best way to have the compiler 
> auto-generate lables in C code?
> 
> In the broadest sense, what I want is to be able to invoke a 
> macro and have it create a unique label each time it is invoked, e.g.
> 
> #define MyUniqueLabelMacro()      // your wizard code here
> 
> and use it like this:
> 
> {
>   ...
>   MyUniqueLabelMacro()
>   ...
>   MyUniqueLabelMacro()
> }
> 
> so that it results in
> 
> {
>   ...
>   auniquelabel:
>   ...
>   anotheruniquelabel:
> }
> 
> I can do this manually by explicitly passing a label name to 
> the macro, but I would prefer (because the labels are only 
> used locally, not outside the scope of any function) to not 
> have to pass an argument to the macro. Each such label must 
> be unique, however, otherwise (in my experience) many 
> assemblers will choke.
> 
> I'd like to see a solution in ANSI C only (no in-line 
> assembly, etc.), but I'll settle for the latter of the former 
> isn't possible.
> 
> I was thinking about something along the lines of using 
> __FILE__ and __LINE__, but the filename is likely to cause 
> problems with its '.'
> character, etc. ...
> 
> Thanks for any help.
> 
> --Andrew E Kalman, Ph.D.
> aek at pumpkin inc dot com
> 
>   
> 
> 
> 
> 
> 
> ------------------------ Yahoo! Groups Sponsor 
> --------------------~--> Make a clean sweep of pop-up ads. 
> Yahoo! Companion Toolbar.
> Now with Pop-Up Blocker. Get it for free!
> http://us.click.yahoo.com/L5YrjA/eSIIAA/yQLSAA/CFFolB/TM
> --------------------------
> ------~-> 
> 
> .
> 
>  
> Yahoo! Groups Links
> 
> 
> 
>  
> 
> 
> 
> 
> 

----- Original Message ----- 
From: "aekalman" <aek@aek@...>
To: <msp430@msp4...>
Sent: Tuesday, November 23, 2004 10:27 PM
Subject: [msp430] How to Auto-generate Unique Labels in C?


> 
> 
> Hi All.
> 
> This is more of a C-centric, rather than MSP430-specific question, but
> with all the compiler vendors here on-line :) I though I'd ask ... I
> think I once saw this done, but I've searched everywhere and
can't
> find it.
> 
> Is there a way / what is the best way to have the compiler
> auto-generate lables in C code?
> 
> In the broadest sense, what I want is to be able to invoke a macro and
> have it create a unique label each time it is invoked, e.g.

I'd use a separate macro-processor like m4.

Leon

Hi Leon, 

> -----Original Message-----
> From: Leon Heller [mailto:leon.heller@leon...] 
> Sent: 23 November 2004 22:39
> To: msp430@msp4...
> Subject: Re: [msp430] How to Auto-generate Unique Labels in C?
> 
> 
> ----- Original Message -----
> From: "aekalman" <aek@aek@...>
> To: <msp430@msp4...>
> Sent: Tuesday, November 23, 2004 10:27 PM
> Subject: [msp430] How to Auto-generate Unique Labels in C?
> 
> > Hi All.
> > 
> > This is more of a C-centric, rather than MSP430-specific 
> question, but
> > with all the compiler vendors here on-line :) I though I'd ask
... I
> > think I once saw this done, but I've searched everywhere and
can't
> > find it.
> > 
> > Is there a way / what is the best way to have the compiler
> > auto-generate lables in C code?
> > 
> > In the broadest sense, what I want is to be able to invoke 
> a macro and
> > have it create a unique label each time it is invoked, e.g.
> 
> I'd use a separate macro-processor like m4.

m4 is nice for some macro processing jobs.  You can even team it up
really well with noweb to get yourself a nice literate programming
system.

--
Paul Curtis, Rowley Associates Ltd  http://www.rowley.co.uk
CrossWorks for MSP430, ARM, and (soon) Atmel AVR processors  

Hi

i am using a similar macro for debugging:

// Debug messages for user and kernel space.
// Preparation because ANSI-/ISO-C99 does not know __FUNCTION__ (gcc feature).
#   ifndef __FUNCTION__
#      define __FUNCTION__ __func__
#   endif
#   if defined(DeBuG) || defined(DEBUG)
#      ifdef __KERNEL__
#         define mc_DEBUG(fmt, args...) { (void)printk(KERN_EMERG
"mc_DEBUG: \"%s\", \"%s\", line %d: ", \
        __FILE__, __FUNCTION__, __LINE__); (void)printk(KERN_EMERG fmt, ##
args); }
#      else
#         define mc_DEBUG(fmt, args...) { (void)fprintf(stderr, "mc_DEBUG:
\"%s\", \"%s\", line %d: ", \
        __FILE__, __FUNCTION__, __LINE__); (void)fprintf(stderr, fmt, ## args);
}
#      endif
#   else
#      define mc_DEBUG(fmt, args...)
#   endif

and several macros for static and dynamic debug level:

// same with dynamic debug level
#   if defined(DeBuG) || defined(DEBUG)
#      define mc_debug(debug_level, fmt, args...)\
   if (debug_level >= DEBUG_LEVEL) mc_DEBUG(fmt, ##args);
#   else
#      define mc_debug(debug_level, fmt, args...)
#   endif

// same with static debug level; expands to no code if not used
#   if ((defined(DeBuG) || defined(DEBUG)) && (DEBUG_LEVEL <= 0))
#      define mc_debug0(fmt, args...) mc_DEBUG(fmt, ##args);
#   else
#      define mc_debug0(fmt, args...)
#   endif

...

In the linux sources you can find hundreds of other and more simple debug
macros.

Rolf


msp430@msp4... schrieb am 23.11.04 23:38:35:
> 
> 
> Hi Andrew:
> 
> #define DoLabel(X) X
> #define MyUniqueLabelMacro() A##DoLabel(__LINE__) 
> 
> This generates identifiers of the type A<linenumber.  This is a use-once
> macro, you can use it exactly once to define a label but can't use it
to
> reference a label.  If the labels are only inside compounds, then they
> are scoped by the compiler so there are no name clashes possible anyway.
> 
> --
> Paul Curtis, Rowley Associates Ltd  http://www.rowley.co.uk
> CrossWorks for MSP430, ARM, and (soon) Atmel AVR processors  
> 
> > -----Original Message-----
> > From: aekalman [mailto:aek@aek@...] 
> > Sent: 23 November 2004 22:28
> > To: msp430@msp4...
> > Subject: [msp430] How to Auto-generate Unique Labels in C?
> > 
> > 
> > 
> > Hi All.
> > 
> > This is more of a C-centric, rather than MSP430-specific 
> > question, but with all the compiler vendors here on-line :) I 
> > though I'd ask ... I think I once saw this done, but I've 
> > searched everywhere and can't find it.
> > 
> > Is there a way / what is the best way to have the compiler 
> > auto-generate lables in C code?
> > 
> > In the broadest sense, what I want is to be able to invoke a 
> > macro and have it create a unique label each time it is invoked, e.g.
> > 
> > #define MyUniqueLabelMacro()      // your wizard code here
> > 
> > and use it like this:
> > 
> > {
> >   ...
> >   MyUniqueLabelMacro()
> >   ...
> >   MyUniqueLabelMacro()
> > }
> > 
> > so that it results in
> > 
> > {
> >   ...
> >   auniquelabel:
> >   ...
> >   anotheruniquelabel:
> > }
> > 
> > I can do this manually by explicitly passing a label name to 
> > the macro, but I would prefer (because the labels are only 
> > used locally, not outside the scope of any function) to not 
> > have to pass an argument to the macro. Each such label must 
> > be unique, however, otherwise (in my experience) many 
> > assemblers will choke.
> > 
> > I'd like to see a solution in ANSI C only (no in-line 
> > assembly, etc.), but I'll settle for the latter of the former 
> > isn't possible.
> > 
> > I was thinking about something along the lines of using 
> > __FILE__ and __LINE__, but the filename is likely to cause 
> > problems with its '.'
> > character, etc. ...
> > 
> > Thanks for any help.
> > 
> > --Andrew E Kalman, Ph.D.
> > aek at pumpkin inc dot com
> > 
> >   
> > 
> > 
> > 
> > 
> > 
> > ------------------------ Yahoo! Groups Sponsor 
> > --------------------~--> Make a clean sweep of pop-up ads. 
> > Yahoo! Companion Toolbar.
> > Now with Pop-Up Blocker. Get it for free!
> > http://us.click.yahoo.com/L5YrjA/eSIIAA/yQLSAA/CFFolB/TM
> > --------------------------
> > ------~-> 
> > 
> > .
> > 
> >  
> > Yahoo! Groups Links
> > 
> > 
> > 
> >  
> > 
> > 
> > 
> > 
> > 
> 
> 
> 
> .
> 
>  
> Yahoo! Groups Links
> 
> 
> 
>  
> 
> 
> 




--- In msp430@msp4..., "Paul Curtis" <plc@r...> wrote: 
> #define DoLabel(X) X
> #define MyUniqueLabelMacro() A##DoLabel(__LINE__) 
> 
> This generates identifiers of the type A<linenumber.  This is a
use-once
> macro, you can use it exactly once to define a
label but can't use
it to
> reference a label.  If the labels are only inside
compounds, then
they
> are scoped by the compiler so there are no name
clashes possible
anyway.

1) Why is DoLabel(x) x required? Why doesn't A##__LINE__ work? Why the
extra subsitution layer?

2) IINM, the scheme you've proposed works fine within a single file,
in C. But I've seen assemblers that can reference EXTERN labels in all
of the C files of a project. To do that, each label name must be
unique (i.e. not allowed to have labels in two files with the same
LINE number). Is there a way in C to get around that?

m4 (dunno what that is) is not an option for me -- must stay within
the ANSI C preprocessor.

Thanks,

--Andrew E. Kalman, Ph.D.
aek at pumpkin inc dot com




Andrew, 

> --- In msp430@msp4..., "Paul Curtis"
<plc@r...> wrote: 
> > #define DoLabel(X) X
> > #define MyUniqueLabelMacro() A##DoLabel(__LINE__)
> > 
> > This generates identifiers of the type A<linenumber.  This is a
> use-once
> > macro, you can use it exactly once to define a label but can't
use
> it to
> > reference a label.  If the labels are only inside compounds, then
> they
> > are scoped by the compiler so there are no name clashes possible
> anyway.
> 
> 1) Why is DoLabel(x) x required? Why doesn't A##__LINE__ 
> work? Why the extra subsitution layer?

As a man of considerable merit in the C preprocessor world, I would have
though you should know the answer to this one.  I'm sure it's a FAQ. 
If
you use A##__LINE__ you'll get A__LINE__ all the time as __LINE__
won't
be expanded.  Wrapping __LINE__ up in a macro that expands to the
expansion of __LINE__ is how you get round this particular problem.

> 2) IINM, the scheme you've proposed works
fine within a 
> single file, in C. But I've seen assemblers that can 
> reference EXTERN labels in all of the C files of a project. 

Boy.  What a nightmare.

> To do that, each label name must be unique (i.e.
not allowed 
> to have labels in two files with the same LINE number). Is 
> there a way in C to get around that?

The only way is to have the user define a unique prefix based on file
name or something else.  I can't see a way to do it in any variant of C.

> m4 (dunno what that is) is not an option for me --
must stay 
> within the ANSI C preprocessor.

m4 is an elderly macro processor distributed with Unix System III, IIRC.
Once a program is put into the Unix pot, it never gets thrown out.

--
Paul Curtis, Rowley Associates Ltd  http://www.rowley.co.uk
CrossWorks for MSP430, ARM, and (soon) Atmel AVR processors  

Hi Rolf.

Neat, but if I read it correctly, the uniqueness of the labels is
hidden in string arguments to printk().

I need the compiler to treat them as individual, unique labels, and
not string literals.

I should look into the Linux source, though ...

Thanks,

--Andrew E. Kalman, Ph.D.
aek at pumpkin inc dot com


--- In msp430@msp4..., <rolf.freitag@e...> wrote:
> Hi
> 
> i am using a similar macro for debugging:
> 
> // Debug messages for user and kernel space.
> // Preparation because ANSI-/ISO-C99 does not know __FUNCTION__ (gcc
feature).
> #   ifndef __FUNCTION__
> #      define __FUNCTION__ __func__
> #   endif
> #   if defined(DeBuG) || defined(DEBUG)
> #      ifdef __KERNEL__
> #         define mc_DEBUG(fmt, args...) { (void)printk(KERN_EMERG
"mc_DEBUG: \"%s\", \"%s\", line %d: ", \
>         __FILE__, __FUNCTION__, __LINE__);
(void)printk(KERN_EMERG
fmt, ## args); }
> #      else
> #         define mc_DEBUG(fmt, args...) { (void)fprintf(stderr,
"mc_DEBUG: \"%s\", \"%s\", line %d: ", \
>         __FILE__, __FUNCTION__, __LINE__);
(void)fprintf(stderr,
fmt, ## args); }
> #      endif
> #   else
> #      define mc_DEBUG(fmt, args...)
> #   endif
> 
> and several macros for static and dynamic debug level:
> 
> // same with dynamic debug level
> #   if defined(DeBuG) || defined(DEBUG)
> #      define mc_debug(debug_level, fmt, args...)\
>    if (debug_level >= DEBUG_LEVEL) mc_DEBUG(fmt, ##args);
> #   else
> #      define mc_debug(debug_level, fmt, args...)
> #   endif
> 
> // same with static debug level; expands to no code if not used
> #   if ((defined(DeBuG) || defined(DEBUG)) && (DEBUG_LEVEL <=
0))
> #      define mc_debug0(fmt, args...) mc_DEBUG(fmt, ##args);
> #   else
> #      define mc_debug0(fmt, args...)
> #   endif
> 
> ...
> 
> In the linux sources you can find hundreds of other and more simple
debug macros.




Rolf,

__FUNCTION__ is not ISO C.
__func__ does not expand to a constant, it is not a preprocessor symbol,
it is generated by the compiler.

So, each of these fails Andrew's requirement os something that can
generate a label name.

--
Paul Curtis, Rowley Associates Ltd  http://www.rowley.co.uk
CrossWorks for MSP430, ARM, and (soon) Atmel AVR processors   

> -----Original Message-----
> From: rolf.freitag@rolf... [mailto:rolf.freitag@rolf...] 
> Sent: 23 November 2004 22:55
> To: msp430@msp4...
> Subject: RE: [msp430] How to Auto-generate Unique Labels in C?
> 
> 
> Hi
> 
> i am using a similar macro for debugging:
> 
> // Debug messages for user and kernel space.
> // Preparation because ANSI-/ISO-C99 does not know 
> __FUNCTION__ (gcc feature).
> #   ifndef __FUNCTION__
> #      define __FUNCTION__ __func__
> #   endif
> #   if defined(DeBuG) || defined(DEBUG)
> #      ifdef __KERNEL__
> #         define mc_DEBUG(fmt, args...) { 
> (void)printk(KERN_EMERG "mc_DEBUG: \"%s\", \"%s\",
line %d: ", \
>         __FILE__, __FUNCTION__, __LINE__); 
> (void)printk(KERN_EMERG fmt, ## args); }
> #      else
> #         define mc_DEBUG(fmt, args...) { 
> (void)fprintf(stderr, "mc_DEBUG: \"%s\", \"%s\",
line %d: ", \
>         __FILE__, __FUNCTION__, __LINE__); 
> (void)fprintf(stderr, fmt, ## args); }
> #      endif
> #   else
> #      define mc_DEBUG(fmt, args...)
> #   endif
> 
> and several macros for static and dynamic debug level:
> 
> // same with dynamic debug level
> #   if defined(DeBuG) || defined(DEBUG)
> #      define mc_debug(debug_level, fmt, args...)\
>    if (debug_level >= DEBUG_LEVEL) mc_DEBUG(fmt, ##args);
> #   else
> #      define mc_debug(debug_level, fmt, args...)
> #   endif
> 
> // same with static debug level; expands to no code if not used
> #   if ((defined(DeBuG) || defined(DEBUG)) && (DEBUG_LEVEL <=
0))
> #      define mc_debug0(fmt, args...) mc_DEBUG(fmt, ##args);
> #   else
> #      define mc_debug0(fmt, args...)
> #   endif
> 
> ...
> 
> In the linux sources you can find hundreds of other and more 
> simple debug macros.
> 
> Rolf
> 
> 
> msp430@msp4... schrieb am 23.11.04 23:38:35:
> > 
> > 
> > Hi Andrew:
> > 
> > #define DoLabel(X) X
> > #define MyUniqueLabelMacro() A##DoLabel(__LINE__)
> > 
> > This generates identifiers of the type A<linenumber.  This is a 
> > use-once macro, you can use it exactly once to define a label but 
> > can't use it to reference a label.  If the labels are only inside

> > compounds, then they are scoped by the compiler so there 
> are no name clashes possible anyway.
> > 
> > --
> > Paul Curtis, Rowley Associates Ltd  http://www.rowley.co.uk 
> CrossWorks 
> > for MSP430, ARM, and (soon) Atmel AVR processors
> > 
> > > -----Original Message-----
> > > From: aekalman [mailto:aek@aek@...]
> > > Sent: 23 November 2004 22:28
> > > To: msp430@msp4...
> > > Subject: [msp430] How to Auto-generate Unique Labels in C?
> > > 
> > > 
> > > 
> > > Hi All.
> > > 
> > > This is more of a C-centric, rather than MSP430-specific 
> question, 
> > > but with all the compiler vendors here on-line :) I 
> though I'd ask 
> > > ... I think I once saw this done, but I've searched 
> everywhere and 
> > > can't find it.
> > > 
> > > Is there a way / what is the best way to have the compiler 
> > > auto-generate lables in C code?
> > > 
> > > In the broadest sense, what I want is to be able to 
> invoke a macro 
> > > and have it create a unique label each time it is invoked, e.g.
> > > 
> > > #define MyUniqueLabelMacro()      // your wizard code here
> > > 
> > > and use it like this:
> > > 
> > > {
> > >   ...
> > >   MyUniqueLabelMacro()
> > >   ...
> > >   MyUniqueLabelMacro()
> > > }
> > > 
> > > so that it results in
> > > 
> > > {
> > >   ...
> > >   auniquelabel:
> > >   ...
> > >   anotheruniquelabel:
> > > }
> > > 
> > > I can do this manually by explicitly passing a label name to the 
> > > macro, but I would prefer (because the labels are only 
> used locally, 
> > > not outside the scope of any function) to not have to pass an 
> > > argument to the macro. Each such label must be unique, however, 
> > > otherwise (in my experience) many assemblers will choke.
> > > 
> > > I'd like to see a solution in ANSI C only (no in-line
assembly, 
> > > etc.), but I'll settle for the latter of the former
isn't 
> possible.
> > > 
> > > I was thinking about something along the lines of using 
> __FILE__ and 
> > > __LINE__, but the filename is likely to cause problems 
> with its '.'
> > > character, etc. ...
> > > 
> > > Thanks for any help.
> > > 
> > > --Andrew E Kalman, Ph.D.
> > > aek at pumpkin inc dot com
> > > 
> > >   
> > > 
> > > 
> > > 
> > > 
> > > 
> > > ------------------------ Yahoo! Groups Sponsor 
> > > --------------------~--> Make a clean sweep of pop-up ads.
> > > Yahoo! Companion Toolbar.
> > > Now with Pop-Up Blocker. Get it for free!
> > > http://us.click.yahoo.com/L5YrjA/eSIIAA/yQLSAA/CFFolB/TM
> > > --------------------------
> > > ------~->
> > > 
> > > .
> > > 
> > >  
> > > Yahoo! Groups Links
> > > 
> > > 
> > > 
> > >  
> > > 
> > > 
> > > 
> > > 
> > > 
> > 
> > 
> > 
> > .
> > 
> >  
> > Yahoo! Groups Links
> > 
> > 
> > 
> >  
> > 
> > 
> > 
> 
> 
> 
> 
> 
> ------------------------ Yahoo! Groups Sponsor 
> --------------------~-->
> $9.95 domain names from Yahoo!. Register anything.
> http://us.click.yahoo.com/J8kdrA/y20IAA/yQLSAA/CFFolB/TM
> --------------------------
> ------~-> 
> 
> .
> 
>  
> Yahoo! Groups Links
> 
> 
> 
>  
> 
> 
> 
> 
> 

At 02:58 PM 11/23/2004, aekalman wrote:

>--- In msp430@msp4..., "Paul Curtis"
<plc@r...> wrote:
> > #define DoLabel(X) X
> > #define MyUniqueLabelMacro() A##DoLabel(__LINE__)
> >
> > This generates identifiers of the type A<linenumber.  This is a
>use-once
> > macro, you can use it exactly once to define a label but can't
use
>it to
> > reference a label.  If the labels are only inside compounds, then
>they
> > are scoped by the compiler so there are no name clashes possible
>anyway.
>
>1) Why is DoLabel(x) x required? Why doesn't A##__LINE__ work? Why the
>extra subsitution layer?

Like I just mentioned on our mailing list, this distinguishes mere mortals 
from Super C programmers :-)

Why? Because ANSI C says so.

The Rationale? I think this is to prevent unintended consequences of having 
# and ## in the source code willy nilly so both # and ## are meaning only 
within the macro definition. I could be wrong though. There used to be a 
hefty "Rationales" book on ANSI C from the committee, but I don't
know if 
they every update it or anything. Remember, this is before PDF :-)

>2) IINM, the scheme you've proposed works fine
within a single file,
>in C. But I've seen assemblers that can reference EXTERN labels in all
>of the C files of a project. To do that, each label name must be
>unique (i.e. not allowed to have labels in two files with the same
>LINE number). Is there a way in C to get around that?

No, but then again, C labels like you mention are not visible outside of 
the function, let alone the files.

>m4 (dunno what that is) is not an option for me --
must stay within
>the ANSI C preprocessor.
>
>Thanks,

// richard (This email is for mailing lists. To reach me directly, please 
use richard at imagecraft.com) 



The 2024 Embedded Online Conference