Thread: Counting macro

  1. #1
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229

    Counting macro

    Hello,

    Is it possible to have a macro expanded to a number incremented after every "instance"?

    I am trying to use it to generate case labels, so they have to be compile-time constants.

    For example -
    Code:
    #define M [...]
    
    switch(...)
    {
    case M:
    ...
    case M:
    ...
    case M:
    ...
    }
    And I want it to preprocess to -
    Code:
    #define M [...]
    
    switch(...)
    {
    case 0:
    ...
    case 1:
    ...
    case 2:
    ...
    }
    Any ideas ?

    Thanks!

  2. #2
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    I just realized, I don't really care about the numbers themselves, as long as they are unique in the switch statement. So I can just use __LINE__ (assuming the switch statement won't be across more than 1 file, and no 2 cases are on the same line).

    I'm still curious about the original problem, though.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Hmm... why do you want to do this in the first place? It seems unnecessary when you can um, type the numbers out yourself.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    Hehe. This is a very long story. I'm trying to do some kind of macro-based cooperative multitasking... using only switch statements. So there could be a lot of labels (need one per "yield()"), and they will be inserted and removed all the time.

    Hopefully I'll have it done today, but here's what I'm trying to do - Piece of Mind » Blog Archive » Primitive Multi-Tasking Using Switch Statement - "Have you moo-ed today?"

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    Woohoo it's working now!

    Warning - probably the ugliest code you've seen in a very long time.

    This is an implementation of cooperative "multitasking" using just switch statements and macros. Why? Piece of Mind » Blog Archive » Primitive Multi-Tasking Using Switch Statement - "Have you moo-ed today?"

    Code:
    #define RESTARTABLE_BEGIN static int restartable_stage = 0; switch(restartable_stage) { case 0:
    #define RESTARTABLE_YIELD restartable_stage = __LINE__; return false; case __LINE__: 
    #define RESTARTABLE_END } restartable_stage = 0; return true;
    Example:
    Code:
    #include <iostream>
    
    
    bool task1()
    {
    	RESTARTABLE_BEGIN;
    
    	std::cout << "t1 -> 1" << std::endl;
    
    	RESTARTABLE_YIELD;
    
    	std::cout << "t1 -> 2" << std::endl;
    
    	RESTARTABLE_YIELD;
    
    	std::cout << "t1 -> 3" << std::endl;
    
    	RESTARTABLE_END;
    }
    
    bool task2()
    {
    	RESTARTABLE_BEGIN;
    
    	std::cout << "t2 -> 1" << std::endl;
    
    	RESTARTABLE_YIELD;
    
    	std::cout << "t2 -> 2" << std::endl;
    
    	RESTARTABLE_YIELD;
    
    	std::cout << "t2 -> 3" << std::endl;
    
    	RESTARTABLE_YIELD;
    
    	std::cout << "t2 -> 4" << std::endl;
    
    	RESTARTABLE_YIELD;
    
    	std::cout << "t2 -> 5" << std::endl;
    
    	RESTARTABLE_END;
    }
    
    int main(int argc, char* argv[])
    {
    	bool task1_done = false;
    	bool task2_done = false;
    
    	while (!(task1_done && task2_done))
    	{
    		if (!task1_done)
    		{
    			task1_done = task1();
    		}
    
    		if (!task2_done)
    		{
    			task2_done = task2();
    		}
    	}
    
    	return 0;
    }
    May be useful in embedded applications if your requirements are simple and can't be bothered to get a real scheduler.

    This program actually triggers a bug in VS2010. It doesn't like __LINE__ as a case label (saying it's not constant) if edit and continue debugging is turned on.

    Workaround provided by putty -
    337 * In particular, if you are getting `case expression not constant'
    338 * errors when building with MS Visual Studio, this is because MS's
    339 * Edit and Continue debugging feature causes their compiler to
    340 * violate ANSI C. To disable Edit and Continue debugging:
    341 *
    342 * - right-click ssh.c in the FileView
    343 * - click Settings
    344 * - select the C/C++ tab and the General category
    345 * - under `Debug info:', select anything _other_ than `Program
    346 * Database for Edit and Continue'.
    347 */

  7. #7
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    Quote Originally Posted by Salem View Post
    Thanks!

    One little problem, though.

    If I have
    Code:
    #define M ... __COUNTER__ ...
    
    M;
    M;
    M;
    All the M's will get the same counter value. Is there a way around that?

  8. #8
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Deviously breaking the token and repasting it together .....
    Code:
    #define M_HELPER(token)  __##token##__
    #define M M_HELPER(COUNTER)
    should do the trick.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. MACRO-need help
    By new-b in forum C Programming
    Replies: 13
    Last Post: 06-22-2009, 10:17 PM
  2. help with macro
    By dudeomanodude in forum C++ Programming
    Replies: 4
    Last Post: 02-12-2008, 01:55 PM
  3. Macro
    By rajashree in forum C Programming
    Replies: 5
    Last Post: 01-10-2008, 05:24 AM
  4. Counting Numbers in Array, not counting last number!
    By metaljester in forum C++ Programming
    Replies: 11
    Last Post: 10-18-2006, 11:25 AM
  5. macro's
    By Steven Snell in forum C Programming
    Replies: 3
    Last Post: 10-14-2002, 12:04 AM