2

For example, how can I get rid of "warning: unnamed struct/union that defines no instances" in the source file, not through compiler command-line options.

I want to define a C macro CONST_BUG_ON, which I use to check some const values at compile time.

#define CONST_BUG_ON(e)        struct  {int a:!(e);}

It gives the warning warning: unnamed struct/union that defines no instances, but in this case it is not a real problem.

Thanks Tom Tanner

#define CONST_BUG_ON_3(e, l) struct buggy##l {int a:!(e);}
#define CONST_BUG_ON_2(e, l) CONST_BUG_ON_3(e, l)
#define CONST_BUG_ON(e) CONST_BUG_ON_2(e, __LINE__)

That's good, but still have some problems: If file a's line 6 contain CONST_BUG_ON(e), and file a was inclued by file b, and line 6 of file b aslo contains CONST_BUG_ON(e), then gcc complains redefine error. Use__COUNTER__ instade of __LINE__ may perfect, but my old compiler does not support __COUNTER__.

Thanks Basile Starynkevitch

#define CONST_BUG_ON(e) do { \
   int tab[__builtin_constant_p(e)?1:-1] = {0}; \
   if (tab[0]) abort(); } while (0)

This is a C statement, can only be place in a function, I really want to use it outside the function.

2
  • the poster have a GCC tag in his question Commented Aug 27, 2012 at 12:47
  • Why is that so important to you? What is the real use case?? Commented Aug 27, 2012 at 14:09

4 Answers 4

3

One way to resolve the compiler’s complaint is that you have an unnamed struct that defines no instances is to give it a name:

#define CONST_BUG_ON(e)        struct ForDebuggingOnly {int a:!(e);}

An alternate way to get the expression testing you want is to declare (but not define) an array that has an illegal size if e is true:

#define CONST_BUG_ON(e)    extern int ForDebuggingOnly[(e) ? -1 : 1]
Sign up to request clarification or add additional context in comments.

2 Comments

If use CONST_BUG_ON several times, this code do not works, gcc complains redefine error.
@yangwen: Use the second method I showed, the one with extern int.
1

You could use macro magic to give yourself a unique ID by passing in the line number

#define CONST_BUG_ON_3(e, l) struct buggy##l {int a:!(e);}
#define CONST_BUG_ON_2(e, l) CONST_BUG_ON_3(e, l)
#define CONST_BUG_ON(e) CONST_BUG_ON_2(e, __LINE__)

That's fairly icky but it does give a unique name each time it is used (the 2nd level of indirection may be spurious, but this is what I have in some code that has stood the test of time).

2 Comments

That's good, but still have some problems: If file "a"'s line 6 contain CONST_BUG_ON(e), and file "a" was inclued by file "b", and line 6 of file "b" aslo contains CONST_BUG_ON(e), then gcc complains redefine error. Use __COUNTER__ instade of LINE may perfect, but my old compiler does not support __COUNTER__.
i think you might have other problems if you have source code set up like that.
1

It looks like what you try is called a compile time assertion or compile time assert macro. There are various ways to do this, usually involving arrays with negative dimension when the assertion fails. Many projects call this macro CT_ASSERT() and there are a bunch of Stackoverflow questions relating to them.

Comments

1

Assuming a recent GCC compiler, you could use __builtin_constant_p to test for compile-time constants, perhaps with

  #define CONST_BUG_ON(e) do { \
       int tab[__builtin_constant_p(e)?1:-1] = {0}; \
       if (tab[0]) abort(); } while (0)

For your question about ignoring some warning, perhaps the GCC diagnostic pragmas could help.

If you want your CONST_BUG_ON to work only in declaration contexts, you might try

  #define CONST_BUG_ON(e) CONST_BUG_AT(e,__LINE__)
  #define CONST_BUG_AT(e,l) \
     extern int tab_##l[__builtin_constant_p(e)?0:-1];

At last you could even customize your GCC compiler (with your specific pragma) perhaps using MELT (a high-level domain specific language to extend GCC), but that will take you days of work.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.