I'm having trouble debugging the following routine, and don't understand
why. It uses a macro, in what I think is a fairly straightforward way,
to do a generic operation.
Background: there are three different struct types, one each
for questions, synonym lists, and comments. Each has a field
named next, which is a self-typed pointer for forming lists, and
a field named idnum, which is an integer. The idnum is a unique
ID reflecting the order in which the statements appeared in the
input file. I'm roundtripping a script-language here (writing
back/recreating the input file after manipulating it
programmatically with programming tools) so I use the ID number
to write things back in the same order they originally appeared.
Each struct type has a separate routine that writes it.
I have a "write progress record" that contains pointers to each
type of linked list.
So.... My macro, WRITEIFLEAST, is supposed to check to make
sure that its first parameter is non-null and that the next
two are either null or have a greater ID number. If all these
conditions are met, it calls the writer (provided as argument 4)
to write the first argument, advances the corresponding pointer
in the progress record, and returns 'success'. I call it once
for the 'current' member of each statement type, in an effort
to write whichever statement comes "next" in the sequence.
I compile using 'gcc -ansi -pedantic' and get the error message,
language.c: In function ‘writestatement’:
language.c:198: error: expected ‘;’ before ‘{’ token
Line 198 is the first use of the macro WRITEIFLEAST. The only
'{' appearing in this line would be the one that opens the body
of the 'elseif' block in the macro, but it makes no sense to
expect a statement terminator between the condition and the
opening of the conditional block it controls, so, aside from
making sure my 'elseif' condition is well-formed (parens match
and everything) I cannot figure out what I should do.
Lines 199 and 200 don't trigger this message, so I think it
has to be something before the first macro use. But I cannot
find it!
########################################################
/* writestatement takes a pointer at a write progress record. If
there are questions, comments, or synonym lists that remain
unwritten, writes whichever has the lowest ID number and returns
1. Otherwise, or in case of error, writes nothing and returns 0.
Note that the token 'output' appears free in this macro, referring
to an output file visible in the scope of writestatement.
*/
#define WRITEIFLEAST(parma, parmb, parmc, writer) \
elseif ((parma != NULL) && \
(parmb == NULL || parmb->idnum > parma->idnum) && \
(parmc == NULL || parmc->idnum > parma->idnum)){ \
writer(parma, output); \
parma = parma->next; \
return(1); \
}
int writestatement(struct writeprogress *prog, FILE *output){
if (prog == NULL || output == NULL ||
(prog->comments == NULL &&
prog->synonyms == NULL &&
prog->questions == NULL)){
return(0);
}
/* writecomment, writesynspec, and writequestion are routines.
A writeprogress struct is a set of pointers to lists of each
of the different statement types.
All 3 record types have a field named idnum and a self-typed
pointer named next; other fields vary. */
WRITEIFLEAST(prog->comments, prog->synonyms, prog->questions, writecomment)
WRITEIFLEAST(prog->synonyms, prog->comments, prog->questions, writesynspec)
WRITEIFLEAST(prog->questions, prog->synonyms, prog->comments, writequestion)
else return(0);
}
#undef WRITEIFLEAST
##############################################################
Anyway, because I was baffled, I ran 'gpp language.c' to see what
was getting generated, and the relevant bit of code is this (I
have added whitespace and one comment for readability, but neither
added nor removed other tokens).
Unfortunately I am *still* baffled. I do not understand what is
wrong with the expanded code. But when I paste it in for the macro
version above, I still get the same error. And it still refers to
expecting a semicolon between the first elseif condition and the
corresponding body, which still makes no sense whatsoever.
##############################################################
int writestatement(struct writeprogress *prog, FILE *output){
if (prog == ((void *)0) || output == ((void *)0) ||
(prog->comments == ((void *)0) && prog->synonyms == ((void *)0) &&
prog->questions == ((void *)0)))
return(0);
elseif
((prog->comments != ((void *)0)) &&
(prog->synonyms == ((void *)0) || prog->synonyms->idnum > prog->comments->idnum) &&
(prog->questions == ((void *)0) || prog->questions->idnum > prog->comments->idnum))
/* here is the location that the compiler is complaining about! */ {
writecomment(prog->comments, output);
prog->comments = prog->comments.next;
return(1);
}
elseif
((prog->synonyms != ((void *)0)) &&
(prog->comments == ((void *)0) || prog->comments->idnum > prog->synonyms->idnum) &&
(prog->questions == ((void *)0) || prog->questions->idnum > prog->synonyms->idnum)){
writesynspec(prog->synonyms, output);
prog->synonyms = prog->synonyms.next;
return(1);
}
elseif
((prog->questions != ((void *)0)) &&
(prog->synonyms == ((void *)0) || prog->synonyms->idnum > prog->questions->idnum) &&
(prog->comments == ((void *)0) || prog->comments->idnum > prog->questions->idnum)) {
writequestion(prog->questions, output);
prog->questions = prog->questions.next;
return(1);
}
else return(0);
}
################################################################
TIA guys. Any help in understanding this would be most appreciated.
Bear
|
|
0
|
|
|
|
Reply
|
bear (1215)
|
2/2/2010 9:03:38 PM |
|
On February 2, 2010 16:03, in comp.lang.c, bear@sonic.net wrote:
>=20
> I'm having trouble debugging the following routine, and don't underst=
and
> why. It uses a macro, in what I think is a fairly straightforward wa=
y,
> to do a generic operation.
>=20
> Background: there are three different struct types, one each
> for questions, synonym lists, and comments. Each has a field
> named next, which is a self-typed pointer for forming lists, and
> a field named idnum, which is an integer. The idnum is a unique
> ID reflecting the order in which the statements appeared in the
> input file. I'm roundtripping a script-language here (writing
> back/recreating the input file after manipulating it
> programmatically with programming tools) so I use the ID number
> to write things back in the same order they originally appeared.
>=20
> Each struct type has a separate routine that writes it.
>=20
> I have a "write progress record" that contains pointers to each
> type of linked list.
>=20
> So.... My macro, WRITEIFLEAST, is supposed to check to make
> sure that its first parameter is non-null and that the next
> two are either null or have a greater ID number. If all these
> conditions are met, it calls the writer (provided as argument 4)
> to write the first argument, advances the corresponding pointer
> in the progress record, and returns 'success'. I call it once
> for the 'current' member of each statement type, in an effort
> to write whichever statement comes "next" in the sequence.
>=20
> I compile using 'gcc -ansi -pedantic' and get the error message,
>=20
> language.c: In function =E2=80=98writestatement=E2=80=99:
> language.c:198: error: expected =E2=80=98;=E2=80=99 before =E2=80=98{=
=E2=80=99 token
>=20
> Line 198 is the first use of the macro WRITEIFLEAST. The only
> '{' appearing in this line would be the one that opens the body
> of the 'elseif' block in the macro, but it makes no sense to
> expect a statement terminator between the condition and the
> opening of the conditional block it controls, so, aside from
> making sure my 'elseif' condition is well-formed (parens match
> and everything) I cannot figure out what I should do.
>=20
> Lines 199 and 200 don't trigger this message, so I think it
> has to be something before the first macro use. But I cannot
> find it!
>=20
>=20
> ########################################################
>=20
> /* writestatement takes a pointer at a write progress record. If
> there are questions, comments, or synonym lists that remain
> unwritten, writes whichever has the lowest ID number and returns
> 1. Otherwise, or in case of error, writes nothing and returns 0.
>=20
> Note that the token 'output' appears free in this macro, referring=
> to an output file visible in the scope of writestatement.
> */
>=20
>=20
> #define WRITEIFLEAST(parma, parmb, parmc, writer) \
> elseif ((parma !=3D NULL) && \
> (parmb =3D=3D NULL || parmb->idnum > parma->idnum) && \=
> (parmc =3D=3D NULL || parmc->idnum > parma->idnum)){ \=
=20
"elseif" is not a C keyword. Perhaps the compiler sees it as a function=
call.
If so, then the compiler would expect some sort of statement-ending con=
tent
(a semicolon, or an "else" statement to match the previous "if" stateme=
nt)
between the end of the function call parameters and the start of the ne=
xt
compound statement.
Consider changing your macro to read
#define WRITEIFLEAST(parma, parmb, parmc, writer) \
else if ((parma !=3D NULL) && \
etc.
> writer(parma, output); \
> parma =3D parma->next; \
> return(1); \
> }
>=20
> int writestatement(struct writeprogress *prog, FILE *output){
>=20
> if (prog =3D=3D NULL || output =3D=3D NULL ||
> (prog->comments =3D=3D NULL &&
> prog->synonyms =3D=3D NULL &&
> prog->questions =3D=3D NULL)){
> return(0);
> }
> /* writecomment, writesynspec, and writequestion are routines.
> A writeprogress struct is a set of pointers to lists of each
> of the different statement types.
> All 3 record types have a field named idnum and a self-typed
> pointer named next; other fields vary. */
> WRITEIFLEAST(prog->comments, prog->synonyms, prog->questions,
> writecomment) WRITEIFLEAST(prog->synonyms, prog->comments,
> prog->questions, writesynspec) WRITEIFLEAST(prog->questions,
> prog->synonyms, prog->comments, writequestion)
>=20
> else return(0);
> }
[snip]
--=20
Lew Pitcher
Master Codewright & JOAT-in-training | Registered Linux User #112576
Me: http://pitcher.digitalfreehold.ca/ | Just Linux: http://justlinux.c=
a/
---------- Slackware - Because I know what I'm doing. ----=
--
|
|
0
|
|
|
|
Reply
|
Lew
|
2/2/2010 9:11:29 PM
|
|
On 2010-02-02, Ray <bear@sonic.net> wrote:
> #define WRITEIFLEAST(parma, parmb, parmc, writer) \
> elseif ((parma != NULL) && \
> (parmb == NULL || parmb->idnum > parma->idnum) && \
> (parmc == NULL || parmc->idnum > parma->idnum)){ \
> writer(parma, output); \
> parma = parma->next; \
> return(1); \
> }
Defining macros for fragments of a statement is a bad idea, probably.
And note that C does not have an elseif keyword. It's ``else if''.
This ``else if'' idiom means that you have an else clause, and that clause is
an if statement. It's usually formated in a vertical fashion.
Writing it as follows clarifies the true nesting of the syntax:
if (...)
...
else if (....)
...
else if (....)
...
else
...
but this ``if/else ladder'' is usually collapsed like this:
if (...)
...
else if (....)
...
else if (....)
...
else
|
|
0
|
|
|
|
Reply
|
Kaz
|
2/2/2010 9:14:27 PM
|
|
Kaz Kylheku wrote:
> Defining macros for fragments of a statement is a bad idea, probably.
Eh. I allow it to myself when the #define and #undef are on the same
screen, with all the macro calls between them. If it were a macro that
could be called "from anywhere" as the saying goes, then yes, I'd want
to make it more function-like and complete unto itself.
> And note that C does not have an elseif keyword. It's ``else if''.
Ding! That was it. Thank you, I was getting C crossed up with some
other language. I may have too many languages in my head now to ever
be truly free of this effect. One side effect of having something
like that pointed out is that now I feel like an idiot for having
asked in the first place. Sigh.
Thanks again,
Bear
|
|
0
|
|
|
|
Reply
|
Ray
|
2/3/2010 3:21:46 AM
|
|
On 3 Feb, 03:21, Ray <b...@sonic.net> wrote:
> Kaz Kylheku wrote:
> > Defining macros for fragments of a statement is a bad idea, probably.
>
> Eh. =A0I allow it to myself when the #define and #undef are on the same
> screen, with all the macro calls between them. =A0If it were a macro that
> could be called "from anywhere" as the saying goes, then yes, I'd want
> to make it more function-like and complete unto itself.
>
> > And note that C does not have an elseif keyword. It's ``else if''.
>
> Ding! =A0That was it. =A0Thank you, I was getting C crossed up with some
> other language. =A0I may have too many languages in my head now to ever
> be truly free of this effect. =A0One side effect of having something
> like that pointed out is that now I feel like an idiot for having
> asked in the first place. Sigh. =A0
its always abvious when you know the answer
|
|
0
|
|
|
|
Reply
|
Nick
|
2/3/2010 9:02:55 AM
|
|
|
4 Replies
170 Views
(page loaded in 0.198 seconds)
Similiar Articles: Run awk95 using VBA Shell(...) in Excel 2000 - comp.lang.awk ...Thanks for any help on using Shell or keeping the DOS ... Outgoing ... api.opengl... functions, like macros, use ... is reformatting that data using EXCEL ... secret that ... gdb (linux) "print" command clears memory corruption - so how do I ...> I am not asking you to debug my program, nor for help ... tends to be a highly optimized inlined function/macro ... although the reason why this occurs remains a mystery ... Can anyone help me with assembly language? - comp.lang.asm.x86 ...Create a macro named mMult32 that multiplies two unsigned 32-bit ... Mystery font. - comp.fonts Can anyone help me with assembly language? - comp.lang.asm.x86 ... error LNK2020: Unresolved token - comp.lang.cRead this thread, maybe it can > help you: > > http ... (If it's a macro, it makes me wonder why the heck they ... =====> Secret Video CLIPS <===== 0 1 shynee4u (11) Invisible window, like console app - comp.os.ms-windows.programmer ...It is just a modal dialog that allows entry of macro ... getting a basic understanding and removing the mystery and ... > >Any help or ideas would be greatly appreciated ... Why won't SAS fix PROC EXPORT - comp.soft-sys.sas... first. or last. - comp.soft-sys.sas Re: Proc SQL help ... Is this a macro bug??? - comp.soft-sys.sas... str),dlm ... why ... as well have used %UPCASE or for more mystery %FIX ... SW2005 SP0: How do I output a (*.dwg), or (*.dxf) file? - comp.cad ...I'll let you in on the secret when I figure it out myself ... the Solidworks 2005 Online User's Guide (under Help tab ... Pre-select a face or plane, run the macro, and a dxf is ... MD5 Hash - comp.lang.c++> Can you help me with a little code example? Not ... Kraus <philipp.kraus@flashpixx.de> spake the secret code ... unique string identifier using md5() function from macro ... Xilinx ISE 7.1 - comp.arch.fpgaXilinx ISE 7.1 : Macro search path in Transalate 1 90 ... I know Xilinx keeps its bit file header format secret. ... ... Help! Signed Number Representation in Xilinx Testbench ... Automating the Software Installation using Shell script - comp ...... teaser.fr/~amajorel/> "No meetings were held, nor secret ... Expect scripting on HP - help please - comp.sys.hp.hpux ... Help Required: Automating Putty Screen using VBA (Macros ... Excel - Macro Recording Mystery - I am trying... - Free Excel HelpMacro Recording Mystery - I am trying to record a macro The message displays... - Free Excel Help Night Macro - a secret weapon | Up Close with NatureNight Macro - a secret weapon ... That way you don't need someone to help you shine light on your macro subject. 7/22/2012 9:30:30 PM
|