tags:

views:

203

answers:

8

While sounding nonsensical.....

I want a Constant where every time you use it it will increment by 1

int x;
int y;
x = INCREMENTING_CONSTANT;
y = INCREMENTING_CONSTANT;

where x == 1; and y == 2

Note I don't want y = INCREMENTING_CONSTANT+1 type solutions.

Basically I want to use it as a compile time unique ID ( generally it wouldn't be used in code like the example but inside another macro)

A: 

Well, it's not constant then, is it? ;)

You can do this with a function:

int id() {
  static int i = 0;
  return ++i;
}

x = id();
y = id();

As shown, this is not thread-safe. To do that you would need to protect this with a mutex, or use a compiler/platform-specific atomic incrementer.

Tim
well, compile time constant :) which is where your answer totally fails! :)hence my question, how to make an incrementing compile time constant! much like ____LINE____ changes depending what line of code you are on :)
Keith Nicholas
I don't think this is quite what he wants. This will generate a new value at run time each time the function is called. I think he wants the value to be calculate once at compile time, then the same value is used every time that line is run.
Mark Byers
A: 

An "incrementing constant" is an oxymoron. You cannot do this at compile time.

richb
seems like one, but the "constant" part refers to being constant at compile time rather than the symbol.
Keith Nicholas
Actually it is lots of constant values, each one greater than the one before
David Sykes
+1  A: 

You may be able to put something together using Boost.Preprocessor (Works with C) and BOOST_PP_COUNTER

Example given on the docs page:

#include <boost/preprocessor/slot/counter.hpp>   
BOOST_PP_COUNTER // 0

#include BOOST_PP_UPDATE_COUNTER()   
BOOST_PP_COUNTER // 1

#include BOOST_PP_UPDATE_COUNTER()  
BOOST_PP_COUNTER // 2

#include BOOST_PP_UPDATE_COUNTER()
BOOST_PP_COUNTER // 3

Translated into what you want

#include <boost/preprocessor/slot/counter.hpp> 

int x = BOOST_PP_COUNTER; // 0

#include BOOST_PP_UPDATE_COUNTER()   
int y = BOOST_PP_COUNTER;// 1

#include BOOST_PP_UPDATE_COUNTER()  
int z = BOOST_PP_COUNTER; // 2

You could also use slots (slightly more flexible at the cost of more code than the above solution):

#include <boost/preprocessor/slot/slot.hpp>

#define BOOST_PP_VALUE 0 //ensure 0 to start
#include BOOST_PP_ASSIGN_SLOT(1) 
int a = BOOST_PP_SLOT(1); //0

#define BOOST_PP_VALUE 1 + BOOST_PP_SLOT(1)
#include BOOST_PP_ASSIGN_SLOT(1) 
int b = BOOST_PP_SLOT(1); //1
Yacoby
+4  A: 

If you just need something unique ID ish, can you use the __LINE__ preprocessor symbol? It's not what you're asking for, but it might work for your purposes.

Stephen Canon
Agree, I always use '__LINE__' for same kinds of things I see '__COUNTER__' used.
Dan Olson
__LINE__ Is what I want to move away from using
Keith Nicholas
+5  A: 

It's not standard, but some compilers support the __COUNTER__ macro. See http://stackoverflow.com/questions/652815/has-anyone-ever-had-a-use-for-the-counter-pre-processor-macro

quinmars
+1  A: 

I've often wished for compile-time variables. However, the easiest thing to do would just be to define constants for each one invididually.

The answer above me's thread problem could be solved by the use of a functionoid in some global state class or a similar sort of solution if you're using C rather than C++.

You could also try using an xmacro. Create a new file, let's call it xmacro.h

INCREMENTING_CONSTANT;
#define INCREMENTING_CONSTANT INCREMENTING_CONSTANT + 1

Then, in a standard header,

#define INCREMENTING_CONSTANT 0
#define USE_INCREMENTING_CONSTANT #include "xmacro.h"

const int x = USE_INCREMENTING_CONSTANT

I haven't tested this, but xmacros have some awesome power that regular macros can't use, like defs/undefs, and my gut says it should work. The preprocessor is powerful, but rather dumb, so it could fail.

DeadMG
this looks promising....
Keith Nicholas
This won't work - the preprocessor doesn't see directives that result from macro expansion.
caf
A: 

Do you want x and y to be constants themselves? If so the easiest and cleanest thing to do may be to use an anonymous enumeration:

enum {
    x = 1,
    y
    /* Add new ones here. */
};

This means you need only add a new name to that list and it will be given the next integer value. This is a useful trick where you don't care what the values are (outside runtime), as long as their distinct. For instance, when assigning identifiers to controls in a GUI, you often see:

enum {
    button1_id = FIRST_USER_ID,
    button2_id,
    combo_id,
    ...
}

Some GUI frameworks provide a GetUserId() function that will generate a new one (using an internal static variable); but I think this happens at runtime. It's also a bit tedious to see so many calls to it in succession.

button1_id = GetUserId();
button2_id = GetUserId();
combo_id = GetUserId();
...
Edmund
sadly no, I can't use the enum thing, its completely unknown how many items there may be.
Keith Nicholas
I'm not sure why that's a problem. Why is it any harder to add a new item to an enumeration than it is to (say) add another line of code to initialise it to some constant, elsewhere?
Edmund
because the macro may appear at any point in the code. Most likely it will be in the body of a function.... and another Macro would be in the body of another function etc etc, there will be an arbitrary amount of references to the macro in many different functions. Each time the macro appears I want it to increment by 1
Keith Nicholas
A: 

Here's an ugly way to implement it.

static int _counter=0;
#define INCREMENTING_CONSTANT (_counter++)
JayM
again, this is not a compile time constant, its runtime..
Keith Nicholas