0

I am trying to define a 'variable' with a macro which can later be used as a constant value ...I have now run out of ideas and wondering if anyone can tell me if I've missed anything:

This is what I originally coded, but C does not recognise 'name' as a constant qv. compile error C2099: initializer is not a constant

#define DECL(name,value)  static const unsigned long int  name = value
DECL(FOO, 0xFFFFFFFF)

My next attempt was to write a macro that would #define the value for me ...But the compiler complains about the embedded # : "error: '#' is not followed by a macro parameter" qv. Escaping a # symbol in a #define macro?

#define DECL(name,value)  #define name (value)UL
DECL(FOO, 0xFFFFFFFF)

At ^-this-^ link, ybungalobill claims v-this-v works ... but it doesn't

#define DECL(hash, name, value)  hash define name (value)UL  
DECL(#, FOO, 0xFFFFFFFF)

I managed to get my code to compile with this enum trick (inspired by the first link) ...it works on my computer, but as this issue is ultimately about creating portable code [portable between languages as well as platforms!] I am worried about the sizeof and signed'ness of the value. qv. What is the size of an enum in C?

#define DECL(name,value)  enum { name = value } ;
DECL(FOO, 0xFFFFFFFF)

Here are some lines of code which may use the above FOO value:

int array[FOO];
static const unsigned long int  BAR = FOO + 1 ;
int main (void) {
    unsigned long int  var1 = FOO;
    printf("%d - %d\n", FOO, sizeof(FOO));
}
Community
  • 1
  • 1
BlueChip
  • 143
  • 2
  • 13
  • 3
    This `#define DECL(name,value) static const unsigned long int name = value ; DECL(FOO, 0xFFFFFFFF)` should compile perfectly, your compiler is crazy or there is something that you didn't post. You even can make it `#define DECL(name,value) static const unsigned long int name = value ## UL`, and remove the `;`, it's not good to put it in that kind of macro. – Iharob Al Asimi May 21 '15 at 17:12
  • http://ideone.com/ng4e0a Can´t reproduce the first error => No problem here. – deviantfan May 21 '15 at 17:13
  • @iharob Sorry forgot that; now it´s C: http://ideone.com/UJsHYF – deviantfan May 21 '15 at 17:15
  • 1
    Yes, the `;` in the first marco is bad form on my behalf ... In the first link, @AnT describes why the first example does not create something which C recognises as a Constant - despite the use of the keyword 'const'. – BlueChip May 21 '15 at 17:37
  • 1
    @BlueChip: `const` doesn't mean "constant" in C; it means read-only. – Keith Thompson May 21 '15 at 18:14
  • 2
    `void main(void)` should be `int main(void)`. If your instructor, tutorial, or text book told you to use `void main(void)`, please find a better one. – Keith Thompson May 21 '15 at 18:20

2 Answers2

3

A macro definition cannot include preprocessor directives, so you can't #define something that expands to another #define.

The const keyword in C doesn't mean "constant"; it means "read-only". A "constant" expression is one that can be evaluated at compile time. A const object is one whose value may not be modified. For example:

const int r = rand();

r is const, meaning you can't modify it after it's been initialized, but it's not "constant" (it can't be, since the value returned by rand() can't be determined until run time).

Using a constant expression as the initializer doesn't change this. (It does in C++.)

The usual way to define a named constant in C is to define it directly as a macro. For example, rather than

#define DECL(name,value)  #define name (value)UL
DECL(FOO, 0xFFFFFFFF)

just write:

#define FOO 0xFFFFFFFFUL

For the special case of constants of type int, you can use an enum declaration:

enum { max = 1000 };

This defines an anonymous enumeration type and a constant max of that type. max is a constant of type int. It's defined that way for historical reasons; it would probably make more sense if max were of the enumeration type (as it is in C), but it isn't.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
0

Your issue is not related to macros in any way.

I am trying to define a 'variable' [...] which can later be used as a constant value

You cannot do this in the sense that this variable can be use as an initialiser.

It would stay a variable.

For further reading: Error "initializer element is not constant" when trying to initialize variable with const

Community
  • 1
  • 1
alk
  • 69,737
  • 10
  • 105
  • 255