Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Macro to assign unique number to a source file

Reply
Thread Tools

Macro to assign unique number to a source file

 
 
celephicus
Guest
Posts: n/a
 
      07-22-2010
Greetings

I use a macro below to get a guaranteed unique number to identify
source files for asserts in a system with very little memory. This
works fine, but sometimes braindead compilers do not optimise away the
dummy function, so it appears in the object file. Is there another way
of checking for no duplicates in "C"?

#define FILENUM(n) \
void errorHandlerDummyFunctionForCheckingFileNumber_##n (void) {} \
enum { F_NUM = (n) }

TomH
 
Reply With Quote
 
 
 
 
Thad Smith
Guest
Posts: n/a
 
      07-22-2010
celephicus wrote:

> I use a macro below to get a guaranteed unique number to identify
> source files for asserts in a system with very little memory. This
> works fine, but sometimes braindead compilers do not optimise away the
> dummy function, so it appears in the object file. Is there another way
> of checking for no duplicates in "C"?
>
> #define FILENUM(n) \
> void errorHandlerDummyFunctionForCheckingFileNumber_##n (void) {} \
> enum { F_NUM = (n) }


I would create a separate header file
filenums.h:
enum {
FILEA=1,
FILEB=2,
FILEC=3};

In file filea.c:
#include "filenums.h"
#define F_NUM FILEA

Keep the entries in filenums.h in numeric order, which allows you to easily
verify uniqueness manually. You could, of course, omit the explicit enum
assignment, but then the numeric value isn't obvious. You could also write a
utility to verify uniqueness and run it as part of the build process.

--
Thad
 
Reply With Quote
 
 
 
 
Ian Collins
Guest
Posts: n/a
 
      07-22-2010
On 07/22/10 12:57 PM, celephicus wrote:
> Greetings
>
> I use a macro below to get a guaranteed unique number to identify
> source files for asserts in a system with very little memory. This
> works fine, but sometimes braindead compilers do not optimise away the
> dummy function, so it appears in the object file. Is there another way
> of checking for no duplicates in "C"?


One bodge I have used on small system is to log the PC and determine the
function form the map file..

--
Ian Collins
 
Reply With Quote
 
celephicus
Guest
Posts: n/a
 
      07-22-2010

>
> I would create a separate header file
> filenums.h:
> enum {
> * *FILEA=1,
> * *FILEB=2,
> * *FILEC=3};
>
> In file filea.c:
> #include "filenums.h"
> #define F_NUM FILEA
>
>


Good idea, because the information is defined in exactly one place,
not spread over all source files. Plus I can easily find the relevant
file relating to a filenumber from one source file, previously I was
using "grep FILENUM *.c". And any decent scripting language can
autogenerate the enum in about 3 lines.

TomH
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      07-24-2010
On 7/21/2010 8:57 PM, celephicus wrote:
> Greetings
>
> I use a macro below to get a guaranteed unique number to identify
> source files for asserts in a system with very little memory. This
> works fine, but sometimes braindead compilers do not optimise away the
> dummy function, so it appears in the object file. Is there another way
> of checking for no duplicates in "C"?
>
> #define FILENUM(n) \
> void errorHandlerDummyFunctionForCheckingFileNumber_##n (void) {} \
> enum { F_NUM = (n) }


The errorHandler... thing is to help you detect accidental re-use
of identical `n' values in different files, is that it? Then if the
compiler were to remove the function, what would happen to your error
detection?

Also, calling a compiler "braindead" because it compiles a function
you told it to compiler seems a little harsh. Seems to me the smell of
cranial necrosis arises from a different source entirely ...

--
Eric Sosman
http://www.velocityreviews.com/forums/(E-Mail Removed)lid
 
Reply With Quote
 
Shao Miller
Guest
Posts: n/a
 
      07-28-2010
I don't know if you might be interested in counting in headers or not,
but:
-----
/* foo.h */
#define MAGIC_COUNT_NEXT foo
#include "magic_count.h"
#define MAGIC_COUNT_CUR foo

/* ... */

/* End of foo.h */
-----
/* bar.h */
#define MAGIC_COUNT_NEXT bar
#include "magic_count.h"
#define MAGIC_COUNT_CUR bar

/* ... */

/* End of bar.h */
-----
/* baz.h */
#define MAGIC_COUNT_NEXT baz
#include "magic_count.h"
#define MAGIC_COUNT_CUR baz

/* ... */

/* End of baz.h */
-----
#ifdef MAGIC_COUNT_USAGE
/*
* magic_count.h (C) 2010 Shao Miller
* Use and adaptation permitted, if credit for origin is included.
*
* Usage:
*
* #define MAGIC_COUNT_NEXT foo
* #include "magic_count.h"
* #define MAGIC_COUNT_CUR foo
*
* Then MAGIC_COUNT will be #defined to a size_t
* integer constant expression
*/
#endif

#ifndef MAGIC_COUNT_CUR
#ifdef MAGIC_COUNT
#error "You forgot to #define MAGIC_COUNT_CUR after #including"
#else
#define MAGIC_COUNT 0
#endif
#define MAGIC_COUNT_FIRST 1
#define MAGIC_COUNT_PASTE2(x,y) x ## y
#define MAGIC_COUNT_PASTE(x,y) MAGIC_COUNT_PASTE2(x,y)
#endif

#ifndef MAGIC_COUNT_NEXT
#error "You forgot to #define MAGIC_COUNT_NEXT before #inlcuding"
#endif

#ifdef MAGIC_COUNT_INC
#error "You already have MAGIC_COUNT_INC #defined"
#endif

#define MAGIC_COUNT_INC() \
\
struct MAGIC_COUNT_PASTE(MAGIC_COUNT_S_, MAGIC_COUNT_NEXT) {\
char (*count)[MAGIC_COUNT + 1]; }

MAGIC_COUNT_INC();

#if MAGIC_COUNT_FIRST
#undef MAGIC_COUNT
#define MAGIC_COUNT \
\
(sizeof \
*(((struct MAGIC_COUNT_PASTE(MAGIC_COUNT_S_,MAGIC_COUNT_CUR) *)0)-
>count)\

)
#undef MAGIC_COUNT_FIRST
#endif

#undef MAGIC_COUNT_INC
#undef MAGIC_COUNT_NEXT
#ifdef MAGIC_COUNT_CUR
#undef MAGIC_COUNT_CUR
#endif
/* End of magic_count.h */
-----
/* main.c */
#include "foo.h"
#include "bar.h"
#include "baz.h"

int main(void) {
return (int)MAGIC_COUNT;
}

/* End of main.c */
-----

It might be fun for counting purposes.
 
Reply With Quote
 
Shao Miller
Guest
Posts: n/a
 
      07-28-2010
Probably won't be submitting that for any obfuscated code contests, so
'typedef'fing a simple 'char[XXX]' type and taking its 'sizeof' would
be less challenging to read than the fun 'struct' business. Heheh.
 
Reply With Quote
 
Peter Nilsson
Guest
Posts: n/a
 
      07-28-2010
Thad Smith <(E-Mail Removed)> wrote:
> celephicus wrote:
> > I use a macro below to get a guaranteed unique number
> > to identify source files for asserts in a system with
> > very little memory.


Not the usual assert() macro then?! Do you really need a
number? What do you do with it? What's wrong with __FILE__?

> > This works fine, but sometimes braindead compilers do
> > not optimise away the dummy function,


Well, if you're braindead enough to put in the dummy function...

> > so it appears in the object file. Is there another way
> > of checking for no duplicates in "C"?
> >
> > #define FILENUM(n) \
> > * * void errorHandlerDummyFunctionForCheckingFileNumber_##n
> > (void) {} \
> > * * enum { F_NUM = (n) }

>
> I would create a separate header file
> filenums.h:
> enum {
> * *FILEA=1,
> * *FILEB=2,
> * *FILEC=3};
>
> In file filea.c:
> #include "filenums.h"
> #define F_NUM FILEA
>
> Keep the entries in filenums.h in numeric order, which
> allows you to easily verify uniqueness manually.*You
> could, of course, omit the explicit enum assignment, but
> then the numeric value isn't obvious. *You could also
> write a utility to verify uniqueness and run it as part
> of the build process.


Built in uniqueness...

/* begin header */

#define FILE_NAMES(M,_) \
M( FILE_A, "FileA.c" ) _ \
M( FILE_B, "FileB.c" ) _ \
M( FILE_C, "FileC.c" ) _ \
M( FILE_D, "FileD.c" )

#define COMMA ,
#define SEMI_COLON ;
#define AS_ENUM(a,b) a

enum { FILE_NULL=0, FILE_NAMES(AS_ENUM, COMMA) };

/* end header */

#include <stdio.h>
/* include above header in required files */

#define AS_PRINTF(a,b) printf("%s,%d,\"%s\"\n", #a, a, b)

int main(void)
{
FILE_NAMES(AS_PRINTF, SEMI_COLON);
return 0;
}

Assigned values validator...

/* begin header */

#define FILE_NAMES(M,_) \
M( FILE_A, 1, "FileA.c" ) _ \
M( FILE_B, 2, "FileB.c" ) _ \
M( FILE_C, 3, "FileC.c" ) _ \
M( FILE_D, 2, "FileD.c" )

#define COMMA ,
#define SEMI_COLON ;
#define AS_ENUM(a,b,c) a = b

enum { FILE_NULL=0, FILE_NAMES(AS_ENUM, COMMA) };

/* end header */

#include <stdio.h>
/* include above header in required files */

#define AS_ARRAY(a,b,c) { #a, a }

struct {
const char *enum_name;
int value;
} array[] = { FILE_NAMES(AS_ARRAY, COMMA) };

#define countof(x) (sizeof(x) / sizeof*(x))

int main(void)
{
int okay = 1;
size_t i, j;

for (i = 0; i < countof(array) - 1; i++)
for (j = i + 1; j < countof(array); j++)
if (array[i].value == array[j].value)
{
printf("%s and %s both have value %d\n",
array[i].enum_name,
array[j].enum_name,
array[i].value);
okay = 0;
}

if (okay) puts("okay!");

return 0;
}

--
Peter
 
Reply With Quote
 
Shao Miller
Guest
Posts: n/a
 
      07-28-2010
On Jul 27, 10:08*pm, Shao Miller <(E-Mail Removed)> wrote:
> Probably won't be submitting that for any obfuscated code contests, so
> 'typedef'fing a simple 'char[XXX]' type and taking its 'sizeof' would
> be less challenging to read than the fun 'struct' business. *Heheh.


Or adding to an 'enum' might be even simpler than even that.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Is there a unique method in python to unique a list? Token Type Python 9 09-09-2012 02:13 PM
Proposal: A way to assign a unique id to JS objects javadesigner@yahoo.com Javascript 12 04-08-2009 12:58 PM
list question... unique values in all possible unique spots ToshiBoy Python 6 08-12-2008 05:01 AM
Laptop has a unique identifying code number -- what is this number called? Radium Computer Support 23 07-08-2007 06:38 PM
Please respond with reasonable answers. [Laptop has a unique identifying code number -- what is this number called?] Radium Computer Support 9 07-01-2007 11:22 AM



Advertisments