2
struct info _info;

#define INIT(a, b, c, d)                   \
    struct info _info = {a, b, c, d}

This worked in C, but with the g++ I get:

error: redefinition of ‘info _info’

INIT isn't always called, sometimes _info gets initialised some other way so that's why both ways have to stick around.

Context:

I'm using INIT in a file that is getting compiled with g++, but I also use it in files compiled by gcc. So the problem is: I need this headerfile code to work in both languages, regardless of whether I use the header in a c library or in a c++ library.

Kerrek pointed out I could use #ifdef, so I did this:

#ifndef __cplusplus

struct info _info;
#define INFO(a, b, c, d)                   \
    struct info _info = {a, b, c, d}

#else

struct info _info;
#define INFO(a, b, c, d)                   \
            _info = {a, b, c, d}
#endif

But it still won't work, I'm getting a error: ‘_info’ does not name a type at the line I'm using the macro in my cpp project: INFO("Information", 2 ,"again", 4)

Blub
  • 13,014
  • 18
  • 75
  • 102
  • 2
    Please provide the context in which you use the `INIT` macro and where it fails. Also, are you 100% sure you did not forget the backslash in the macro definition (this would be consistent with the error) ? Please copy and paste the actual erroneous code. – Alexandre C. Nov 02 '11 at 13:24
  • @AlexandreC.I added clarificiaton that I need it to work in both c++ and c – Blub Nov 02 '11 at 13:59
  • 1
    Note: names starting by an underscore are reserved in many contexts, I invite you to switch to another naming convention. – Matthieu M. Nov 02 '11 at 14:06

2 Answers2

3

In C++, you don't say struct in the variable declaration. The following should work:

struct info { int x, y, z, w; };  // type definition (elsewhere in your code)

#define INIT(a, b, c, d) info _info = {a, b, c, d}

INIT(1,2,3,4);

Because the variable name is fixed, this macro can only be used once inside any given scope, which is not obvious. For more flexibility, I'd add the variable name to the macro:

#define DECLARE_AND_INIT(var, a, b, c, d) info var = {a, b, c, d}
DECLARE_AND_INIT(my_info, 4, 5, 6, 7);
Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • I need it to work both in c++ and c, I'm including the code I provided as a header into both a c and c++ project. I'm sorry, I wasn't clear. – Blub Nov 02 '11 at 13:32
  • Err... what? Work with two different languages?? You can use conditional macros conditional on `__cplusplus` I suppose. – Kerrek SB Nov 02 '11 at 13:33
  • 1
    @KerrekSB, using `struct info` is just as valid as using plain `info` in C++. – avakar Nov 02 '11 at 13:40
  • @avakar: the difference is subtle. Sometimes it's the same, sometimes saying `struct` induces a forward declaration... it depends on the context! In the absence of contextual information, I'd prefer to go with the least amount of unforeseeable side effects. – Kerrek SB Nov 02 '11 at 13:42
  • Kerrek, I added a better explanation. Thanks for the tip about the #defines, but something is still not working. – Blub Nov 02 '11 at 14:02
  • @Blub: That's because you wrote something completely different from what I suggested. You *cannot assign* structs like that; the brace syntax only works in the iniitalizer. You have to declare and initialize in one line. Like my second macro. – Kerrek SB Nov 02 '11 at 14:04
0

If memory serves me correctly you can use a typedef and avoid the __cplusplus specific section.

typedef struct taginfo { int x, y, z, w; } info;
info _info;
#define INFO(a,b,c,d) _info = {(a), (b), (c), (d)}

...and this should work in both C and C++.

See Why should we typedef a struct so often in C?

Community
  • 1
  • 1
leander
  • 8,527
  • 1
  • 30
  • 43