On Fri, Nov 6, 2020 at 8:52 PM <newcomer@xxxxxxxxxxxx> wrote: > > Consider that I want to write a macro that, for a list of arguments, will > generate one (or more) lines of code for each argument. For example > > > > [code] > > #define STATES S0, WANTDIGIT, DIGIT, REJECTING, ENDNUMBER, WAVEFORM, > FINISH, ENDOFDATA, OUTPUT_STREAM_ID > > > > typedef enum { STATES} States; > > > > > > States state = S0; > > > > void showState() > > { > > #define show1(x, ...) \ > > case x: Serial.println(#x); break; \ > > __VA_OPT__(show1(__VA_ARGS__)) > > > > switch(state) > > { /* state */ > > show1(STATES); > > } /* state */ > > #undef show1 > > } > > [/code] > > What I expect to generate is > > [code] > > show1(S0, WANTDIGIT, DIGIT, REJECTING, ENDNUMBER, WAVEFORM, FINISH, > ENDOFDATA, OUTPUT_STREAM_ID) > > [/code] > > Which should give me > > [code] > > void showState() > { > > switch(state) > { /* state */ > > case S0: Serial.println("S0"); break; > case WANTDIGIT: Serial.println("WANTDIGIT"); break; > > //..etc. > > case OUTPUT_STREAM_ID: Serial.println("OUTPUT_STREAM_ID"); break; > > } /* state */ > > } // showState > > [/code] > > > > What I get, though, is > > [code] > > C:\Users\admin\OneDrive\Projects\Oscilloscope Tests\PWM_test\PWM_test.ino: > In function 'void showState()': > > PWM_test:39:19: error: expected ':' before ',' token > > 39 | #define STATES S0, WANTDIGIT, DIGIT, REJECTING, ENDNUMBER, > WAVEFORM, FINISH, ENDOFDATA, OUTPUT_STREAM_ID > > | ^ > > C:\Users\admin\OneDrive\Projects\Oscilloscope > Tests\PWM_test\PWM_test.ino:48:10: note: in definition of macro 'show1' > > 48 | case x: Serial.println(#x); break; \ > > | ^ > > C:\Users\admin\OneDrive\Projects\Oscilloscope > Tests\PWM_test\PWM_test.ino:52:12: note: in expansion of macro 'STATES' > > 52 | show1(STATES); > > | ^~~~~~ > > PWM_test:39:19: error: expected primary-expression before ',' token > > 39 | #define STATES S0, WANTDIGIT, DIGIT, REJECTING, ENDNUMBER, > WAVEFORM, FINISH, ENDOFDATA, OUTPUT_STREAM_ID > > | ^ > > C:\Users\admin\OneDrive\Projects\Oscilloscope > Tests\PWM_test\PWM_test.ino:48:10: note: in definition of macro 'show1' > > 48 | case x: Serial.println(#x); break; \ > > | ^ > > C:\Users\admin\OneDrive\Projects\Oscilloscope > Tests\PWM_test\PWM_test.ino:52:12: note: in expansion of macro 'STATES' > > 52 | show1(STATES); > > | ^~~~~~ > > C:\Users\admin\OneDrive\Projects\Oscilloscope > Tests\PWM_test\PWM_test.ino:50:11: warning: enumeration value 'WANTDIGIT' > not handled in switch [-Wswitch] > > 50 | switch(state) > > | ^ > > C:\Users\admin\OneDrive\Projects\Oscilloscope > Tests\PWM_test\PWM_test.ino:50:11: warning: enumeration value 'DIGIT' not > handled in switch [-Wswitch] > > C:\Users\admin\OneDrive\Projects\Oscilloscope > Tests\PWM_test\PWM_test.ino:50:11: warning: enumeration value 'REJECTING' > not handled in switch [-Wswitch] > > C:\Users\admin\OneDrive\Projects\Oscilloscope > Tests\PWM_test\PWM_test.ino:50:11: warning: enumeration value 'ENDNUMBER' > not handled in switch [-Wswitch] > > C:\Users\admin\OneDrive\Projects\Oscilloscope > Tests\PWM_test\PWM_test.ino:50:11: warning: enumeration value 'WAVEFORM' not > handled in switch [-Wswitch] > > C:\Users\admin\OneDrive\Projects\Oscilloscope > Tests\PWM_test\PWM_test.ino:50:11: warning: enumeration value 'FINISH' not > handled in switch [-Wswitch] > > C:\Users\admin\OneDrive\Projects\Oscilloscope > Tests\PWM_test\PWM_test.ino:50:11: warning: enumeration value 'ENDOFDATA' > not handled in switch [-Wswitch] > > C:\Users\admin\OneDrive\Projects\Oscilloscope > Tests\PWM_test\PWM_test.ino:50:11: warning: enumeration value > 'OUTPUT_STREAM_ID' not handled in switch [-Wswitch] > > exit status 1 > > expected ':' before ',' token > > [/code] > > > > What is going wrong here? While the error can be fixed as follows, the C standard forbids a recursive macro, and therefore, you must define separate macros as many as there are levels of a recursion. #define STATES S0, WANTDIGIT, DIGIT, REJECTING, ENDNUMBER, WAVEFORM, FINISH, ENDOFDATA, OUTPUT_STREAM_ID typedef enum { STATES} States; States state = S0; void showState() { #define show1(x, ...) case x: Serial.println(#x); break; \ __VA_OPT__(show1(__VA_ARGS__)) #define expand(fn_to_call, var_to_expand) \ fn_to_call(var_to_expand) switch(state) { /* state */ expand(show1, STATES); } /* state */ #undef expand #undef show1 } That said, your problem is off-topic for this mailing list because your problem is a problem about using the C preprocessor, not GCC. Please ask further questions related to using the C preprocessor (including techniques to easily define different macros for different levels of a recursion) in another place to get the best answers possible. -- Best regards, Tadeus