Increment a number in compile time macro

Discussion in 'C Programming' started by Bin Chen, Sep 7, 2008.

  1. Bin Chen

    Bin Chen Guest

    switch(i) {
    case 1:
    break;
    case 2:
    break;
    [...]
    case N:
    break;

    }

    Now, after some time I want to add a 'case 2' between case 1 and case
    2, the result means every case number after case 2 need to be
    incremented by 1, it there a macro tricks to make life easier? Such
    as:

    switch(i) {
    case AUTO_INC_MACRO:
    break;
    case AUTO_INC_MACRO:
    ....

    Thanks in advance.

    Bin
     
    Bin Chen, Sep 7, 2008
    #1
    1. Advertising

  2. Bin Chen

    Ian Collins Guest

    Bin Chen wrote:
    > switch(i) {
    > case 1:
    > break;
    > case 2:
    > break;
    > [...]
    > case N:
    > break;
    >
    > }
    >
    > Now, after some time I want to add a 'case 2' between case 1 and case
    > 2, the result means every case number after case 2 need to be
    > incremented by 1, it there a macro tricks to make life easier? Such
    > as:
    >

    Use an enum. Never use magic numbers.

    --
    Ian Collins.
     
    Ian Collins, Sep 7, 2008
    #2
    1. Advertising

  3. On Sat, 6 Sep 2008 23:54:08 -0700 (PDT), Bin Chen
    <> wrote:

    >switch(i) {
    >case 1:
    > break;
    >case 2:
    > break;
    >[...]
    >case N:
    > break;
    >
    >}
    >
    >Now, after some time I want to add a 'case 2' between case 1 and case
    >2, the result means every case number after case 2 need to be
    >incremented by 1, it there a macro tricks to make life easier? Such
    >as:
    >
    >switch(i) {
    >case AUTO_INC_MACRO:
    > break;
    >case AUTO_INC_MACRO:


    Macros don't perform calculations. They only perform text
    substitution. And a subsequent appearance of a macro in your code
    will not have access to the result of a previous appearance.

    However, you can do what you want with an enum. Something of the form
    enum {CASE1=1, CASE2, ..., CASEN};
    and change each case label to
    case CASE1:
    ...
    case CASE2:
    etc.

    Later, when you want to insert a case between CASE1 and CASE2, change
    you enum to
    enum {CASE1=1, CASE1A, CASE2, ..., CASEN};
    and insert the new block of code immediately before the CASE2 label.

    To eliminate the rampant confusion after a half-dozen insertions where
    CASE6 may be 7 while CASE10 is 13, I would suggest using identifiers
    that are suggestive of the function to be performed rather than their
    numeric value. Something like
    enum {INSERT=1, DELETE, EDIT, COMPUTE};
    and then you could later amend it to
    enum {INSERT=1, DELETE, EDIT, PRINT, COMPUTE};

    --
    Remove del for email
     
    Barry Schwarz, Sep 7, 2008
    #3
  4. On Sep 7, 7:54 am, Bin Chen <> wrote:

    > switch(i) {
    > case 1:
    >   break;
    > case 2:
    >   break;
    > [...]
    > case N:
    >   break;
    >
    > }
    >
    > Now, after some time I want to add a 'case 2' between case 1 and case
    > 2, the result means every case number after case 2 need to be
    > incremented by 1, it there a macro tricks to make life easier? Such
    > as:
    >
    > switch(i) {
    > case AUTO_INC_MACRO:
    >   break;
    > case AUTO_INC_MACRO:
    > ...


    how about

    #include <stdio.h>

    #define INC(N) (N + 1)

    int main (void)
    {
    int i = 2;

    switch (i)
    {
    case INC(1):
    printf ("A\n");
    break;

    case INC(2):
    printf ("B\n");
    break;
    }

    return 0;
    }

    would this work? Though pre-processor magic of this
    sort is usually not a good idea.

    --
    Nick Keighley
     
    Nick Keighley, Sep 7, 2008
    #4
  5. Nick Keighley <> writes:

    > On Sep 7, 7:54 am, Bin Chen <> wrote:
    >
    >> switch(i) {
    >> case 1:
    >>   break;
    >> case 2:
    >>   break;
    >> [...]
    >> case N:
    >>   break;
    >>
    >> }
    >>
    >> Now, after some time I want to add a 'case 2' between case 1 and case
    >> 2, the result means every case number after case 2 need to be
    >> incremented by 1, it there a macro tricks to make life easier? Such
    >> as:
    >>
    >> switch(i) {
    >> case AUTO_INC_MACRO:
    >>   break;
    >> case AUTO_INC_MACRO:
    >> ...

    >
    > how about
    >
    > #include <stdio.h>
    >
    > #define INC(N) (N + 1)
    >
    > int main (void)
    > {
    > int i = 2;
    >
    > switch (i)
    > {
    > case INC(1):
    > printf ("A\n");
    > break;
    >
    > case INC(2):
    > printf ("B\n");
    > break;
    > }
    >
    > return 0;
    > }
    >
    > would this work? Though pre-processor magic of this
    > sort is usually not a good idea.


    It's not really magic is it? INC(1) is just a funny way to write 2
    (as a constant expression). Are you suggesting the OP uses some
    search-and-replace to change case x: into case INC(x): for the x
    greater then the one they want to add, thus permitting the new case to
    be "slotted in"? If so, then the editor is almost certainly capable of
    doing the arithmetic itself. If not, then I'm not sure how the INC
    macro helps.

    Any literal answer almost misses the point, for me. If the OP is
    adding cases in the middle of an existing range, surely all sorts of
    other parts of the code much change too. Switching to an enum will
    automatically fix these as well (once all the constants are replaced by
    enum names).

    --
    Ben.
     
    Ben Bacarisse, Sep 7, 2008
    #5
  6. Bin Chen

    Moi Guest

    On Sat, 06 Sep 2008 23:54:08 -0700, Bin Chen wrote:

    > switch(i) {
    > case 1:
    > break;
    > case 2:
    > break;
    > [...]
    > case N:
    > break;
    >
    > }
    >
    > Now, after some time I want to add a 'case 2' between case 1 and case 2,
    > the result means every case number after case 2 need to be incremented
    > by 1, it there a macro tricks to make life easier? Such as:
    >
    > switch(i) {
    > case AUTO_INC_MACRO:
    > break;
    > case AUTO_INC_MACRO:
    > ...


    #include <stdio.h>

    #define SWITCH(v) switch ((2*(v))+__LINE__-1)
    #define CASE case __LINE__

    int main(int argc, char *argv[] )
    {
    int ii;

    SWITCH(argc) {
    CASE:
    printf("One!!\n"); break;
    CASE:
    printf("two!!\n"); break;
    CASE:
    printf("three!!\n"); break;
    CASE:
    printf("four!!\n"); break;
    default:
    printf("Unknown %d. Please call QA.\n", argc); break;
    }
    return 0;
    }



    HTH,
    AvK
    ;-)
     
    Moi, Sep 7, 2008
    #6
  7. On Sun, 07 Sep 2008 18:10:32 +0200, Moi <>
    wrote:

    >On Sat, 06 Sep 2008 23:54:08 -0700, Bin Chen wrote:
    >
    >> switch(i) {
    >> case 1:
    >> break;
    >> case 2:
    >> break;
    >> [...]
    >> case N:
    >> break;
    >>
    >> }
    >>
    >> Now, after some time I want to add a 'case 2' between case 1 and case 2,
    >> the result means every case number after case 2 need to be incremented
    >> by 1, it there a macro tricks to make life easier? Such as:
    >>
    >> switch(i) {
    >> case AUTO_INC_MACRO:
    >> break;
    >> case AUTO_INC_MACRO:
    >> ...

    >
    >#include <stdio.h>
    >
    >#define SWITCH(v) switch ((2*(v))+__LINE__-1)
    >#define CASE case __LINE__
    >
    >int main(int argc, char *argv[] )
    >{
    >int ii;
    >
    >SWITCH(argc) {
    >CASE:
    > printf("One!!\n"); break;
    >CASE:
    > printf("two!!\n"); break;
    >CASE:
    > printf("three!!\n"); break;
    >CASE:
    > printf("four!!\n"); break;
    >default:
    > printf("Unknown %d. Please call QA.\n", argc); break;
    > }
    >return 0;
    >}


    Not bad if the requested flexibility ever becomes a higher priority
    than readability. Non-trivial cases could have some pretty long
    lines. And let's hope none of the statements within a case contain
    any macros that might expand to more than one line.

    --
    Remove del for email
     
    Barry Schwarz, Sep 7, 2008
    #7
  8. On Sun, 07 Sep 2008 11:20:30 -0700, Barry Schwarz wrote:
    > And
    > let's hope none of the statements within a case contain any macros that
    > might expand to more than one line.


    A macro can't expand to more than one line.
     
    Harald van Dijk, Sep 7, 2008
    #8
  9. On Sun, 07 Sep 2008 21:14:20 +0200, Harald van D?k <>
    wrote:

    >On Sun, 07 Sep 2008 11:20:30 -0700, Barry Schwarz wrote:
    >> And
    >> let's hope none of the statements within a case contain any macros that
    >> might expand to more than one line.

    >
    >A macro can't expand to more than one line.


    Then the hope is not in vain :)

    For my education, you are saying the preprocessor will merge the lines
    in macros like
    do {\
    many lines of code each ending with \
    } while(0);
    which is often recommended here? Somehow I had the idea the merging
    took place during compilation.

    Which raises a new question. As far as the __LINE__ macro is
    concerned, is the following code one line or two?
    x = 1;\
    y = 3;
    On my system, the answer is two but n1256 (5.1.1.2-2) seems to imply
    it should be one.

    --
    Remove del for email
     
    Barry Schwarz, Sep 8, 2008
    #9
  10. On Sun, 07 Sep 2008 17:31:51 -0700, Barry Schwarz wrote:
    > On Sun, 07 Sep 2008 21:14:20 +0200, Harald van D?k <>
    > wrote:
    >>On Sun, 07 Sep 2008 11:20:30 -0700, Barry Schwarz wrote:
    >>> And
    >>> let's hope none of the statements within a case contain any macros
    >>> that might expand to more than one line.

    >>
    >>A macro can't expand to more than one line.

    >
    > Then the hope is not in vain :)
    >
    > For my education, you are saying the preprocessor will merge the lines
    > in macros like
    > do {\
    > many lines of code each ending with \
    > } while(0);
    > which is often recommended here?


    Yes. This happens before the macro definition is even parsed.

    > Somehow I had the idea the merging
    > took place during compilation.


    It's done in translation phase 2, while handling of preprocessor
    directives such as #define is translation phase 4.

    > Which raises a new question. As far as the __LINE__ macro is concerned,
    > is the following code one line or two?
    > x = 1;\
    > y = 3;
    > On my system, the answer is two but n1256 (5.1.1.2-2) seems to imply it
    > should be one.


    It should be one.
     
    Harald van Dijk, Sep 8, 2008
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    104
    Views:
    11,030
    Jordan Abel
    Oct 28, 2005
  2. Replies:
    99
    Views:
    2,511
    eliza81
    Jun 11, 2010
  3. Carter
    Replies:
    2
    Views:
    510
    Carter
    Mar 4, 2009
  4. Alf P. Steinbach /Usenet
    Replies:
    0
    Views:
    900
    Alf P. Steinbach /Usenet
    May 22, 2011
  5. Peng Yu

    post increment or pre increment?

    Peng Yu, Nov 21, 2008, in forum: Perl Misc
    Replies:
    7
    Views:
    530
    Peter J. Holzer
    Nov 23, 2008
Loading...

Share This Page