[splint-discuss] [splint-discuss glib header and empty #define's

Jack T Mudge III jakykong at theanythingbox.com
Wed Feb 27 14:12:09 PST 2008


> Message: 8
> Date: Wed, 27 Feb 2008 08:37:47 -0800
> From: "Michael Wojcik" <Michael.Wojcik at microfocus.com>
> Subject: Re: [splint-discuss] glib header and empty #define's
> To: "Discussions about the Splint annotation-assisted static
>         analysisproject"        <splint-discuss at cs.virginia.edu>
> Message-ID:
>         <11352F9641010A418AD5057945A3A6590118B289 at MTV-EXCHANGE.microfocus
>.com> Content-Type: text/plain;       charset="us-ascii"
>
> > From: splint-discuss-bounces at cs.virginia.edu
> > [mailto:splint-discuss-bounces at cs.virginia.edu] On Behalf Of
> > Jack T Mudge III
> > Sent: Tuesday, 26 February, 2008 18:19
> >
> > in /usr/include/glib-2.0/glib/gmacros.h
> > /* Guard C code in headers, while including them from C++ */
> > #ifdef  __cplusplus
> > # define G_BEGIN_DECLS  extern "C" {
> > # define G_END_DECLS    }
> > #else
> > # define G_BEGIN_DECLS ;
> > # define G_END_DECLS ;
> > #endif
> >
> > The point of this snippet seems to be to  keep some
> > declarations from causing problems for C++ compilers, which
> > is fine.
>
> Not quite.
>
> C++ implementations will define "__cplusplus", so when this header is
> processed by a C++ implementation, G_BEGIN_DECLS will be defined as a
> macro that expands to "extern "C" {", and G_END_DECLS will be defined as
> a macro that expands to "}".
>
> extern "C" is C++ syntax that tells the implementation that the
> following declaration, or bracketted series of declarations, use the "C"
> linkage convention. It's used to tell C++ that the declarations refer to
> non-C++ code, for reasons that are irrelevant if you're not using C++.
>
> splint is not a C++ implementation, so it should not have __cplusplus
> defined (and won't, unless your configuration or one of the files you're
> processing erroneously defines it).
>



> > The definition G_BEGIN_DECLS and G_END_DECLS, then, should be "" in my
> >
> > source file -- __cplusplus is NOT defined.
>
> No. Read the source again. If __cplusplus is not defined, then
> G_BEGIN_DECLS and G_END_DECLS are both defined as macros that expand to
> a semicolon - NOT an empty string.
>

Wow. I know even less about C++ than I thought I did (and I didn't think I 
knew much). For a moment, I thought I may have made a typo, but reviewing 
the source again, you are absolutely correct. I read that code incorrectly. 

At least using the gcc compiler, the difference between a blank string and a 
semicolon in that context seems insignificant (they both compile, and they 
both do nothing. I'm not sure if there are any technicalities involved, 
however.)

> (I have no idea why the author of that header has them expand to
> semicolons; I can't offhand think of any situation where a linkage
> declaration would be appropriate in C++ and a semicolon would be needed
> in C. But a lot of GNU code is rather poor C.)
>
> > /usr/include/glib/gtypes.h:41:8: Parse Error: Non-function
> > declaration:
> >     G_BEGIN_DECLS : int. (For help on parse errors, see splint -help
> >     parseerrors.)
>
> This implies that you haven't included gmacros.h at all, or it would
> never see a token named G_BEGIN_DECLS.
>
Ok, I thought that implied that it hadn't seen the token, and assumed the 
token was an integer. gmacros.h is included by gtypes.h which is included 
by glib.h. By the time that token is ever used, it's already been defined.

> > I have tried adding #define G_BEGIN_DECLS ; to my source file, and
>
> splint
>
> > complains about a duplicate definition
>
> It's likely, then, that you have gtypes.h being included before
> gmacros.h, so the definition of the G_BEGIN_DECLS macro is only
> encountered after Splint tries to process gtypes.h.
>
including gmacros.h is one of the first thing gtypes.h does, which is why I 
had concluded it was the #define itself that was causing problems.
> Can you produce a small example that demonstrates the problem?

I feel like an idiot right now.

I went to re-produce this error, with a file "test.c" containing
#include <glib/glib.h>
int main  {return 0;}
(which is all I needed to cause the error before).
Which I proceeded to (attempt to) compile using the command
gcc -l glib-2.0 test.c 2>&1|less
And my screen promptly filled with several pages of error messages. Reading 
through the top few, include files weren't found. I compile a more 
elaborate, but very similar file perfectly using the make command in my 
working directory, so I went to check what I might be forgetting, only to 
find `pkg-config --cflags glib-2.0` hidden in my make file's CFLAGS 
variable. Splint passes -I to the preprocessor, and the above backtick 
expression evaluates 
to "-I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include" on my system.

That key oversight was apparently the source of this error.


Thank you for your help (and your insight into what that macro was meant to 
accomplish). With any luck, this will be the only problem I run into!

>
> --
> Michael Wojcik
> Principal Software Systems Developer, Micro Focus



-- 
Sincerely,
Jack Mudge
jakykong at theanythingbox.com

My GPG Public Key can be found at:
https://www.theanythingbox.com/pgp.htm and Below.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part.
Url : http://www.cs.virginia.edu/pipermail/splint-discuss/attachments/20080227/78db21ac/attachment.bin 


More information about the splint-discuss mailing list